讲讲 iOS 开发中的 SOLID 原则

这里每天分享一个 iOS 的新知识,快来关注我吧

前言

在软件工程中,SOLID 原则是五个基本原则,旨在促进更好的软件设计:更可维护、更易于理解、更灵活。对于 iOS 开发者来说,掌握和应用这些原则是非常重要的,因为它们可以帮助你构建出高质量的应用程序。今天准备来尝试介绍下我对这些原则的理解,并提供具体的 iOS 开发例子来说明如何在实践中应用这些原则。

单一职责原则 (SRP)

单一职责原则指的是一个类应该只负责一项任务。在 iOS 开发中,遵循此原则可以避免创建庞大的类,每个类都应该专注于单一的功能。

举个例子,比如你有一个个人中心的控制器 UserProfileViewController,它的职责是展示用户的个人信息,而不应该同时负责从网络获取这些信息。这种职责的分离使得代码更易于维护和测试。

less 复制代码
class UserProfileService {
    func fetchUserProfile(completion: @escaping (UserProfile) -> Void) {
        // 实现网络请求获取用户资料
    }
}

如果你的这个页面有网络请求相关的代码,可以考虑创建另一个类,比如 UserProfileService,在这个类中进行页面需要的数据请求,这样我们就使 UserProfileViewController 遵循了单一职责原则,使其变得更加清晰和易于管理。

开放封闭原则 (OCP)

开放封闭原则强调软件实体(类、模块、函数等)应该对扩展开放,对修改封闭。

什么意思呢,一个类一旦设计开发完成,就应该可以独立完成其工作,而不要对类进行任何修改,如果你想要增加功能,应该通过扩展/集成/实现接口等方式。

在 iOS 开发中,这种原则也很常见,比如我要设计一个图像处理功能的协议 ImageFilter,协议一旦设计完成,就不再更改了,假设这个协议只有一个方法 apply(to:) 输入一个图片,返回一个图片。

swift 复制代码
protocol ImageFilter {
    func apply(to image: UIImage) -> UIImage
}

如果此时我想增加一个模糊滤镜的功能,我可以新建一个类来遵守这个协议,并实现 apply(to:) 方法:

swift 复制代码
class BlurFilter: ImageFilter {
    func apply(to image: UIImage) -> UIImage {
        // 应用模糊滤镜...
        return image
    }
}

这样,任何新的滤镜都可以通过实现ImageFilter协议来创建,从而遵循了开放封闭原则。

里氏替换原则 (LSP)

里氏替换原则其实是针对继承而言的,要求子类能够替换其基类,而不破坏程序的正确性。这意味着子类应该完全实现父类的行为。

在现在的编程语言中基本都符合这个原则,在 iOS 开发中也不例外,一个简单的例子,如果我们有一个 Bird 类和一个 FlyingBird 子类,那么任何 FlyingBird 的实例都应该能够替换Bird的实例。

swift 复制代码
class Bird {
    func layEgg() {
        print("Laying an egg.")
    }
}

class FlyingBird: Bird {
    func fly() {
        print("Flying.")
    }
}

通过确保 FlyingBird 遵循 LSP,我们可以确保我们的代码更加灵活和可靠。

接口隔离原则 (ISP)

接口隔离原则指的是客户端不应该依赖它不使用的接口,这其实跟单一职责有点关系,一个大型接口往往有很多功能,但是继承者往往不需要这么多功能,就需要把大型接口拆分为更小、更具体的接口。

例如,你有一个打印机的类,它拥有打印、扫描、复制等功能,我们可以将打印、扫描和复印功能分解为独立的协议,这样,打印机只需要依赖打印功能、扫描仪就只需要依赖扫描功能,或者选择性的依赖多个功能。

swift 复制代码
// 打印功能
protocol Printer {
    func printDocument(document: Document)
}

// 扫描功能
protocol Scanner {
    func scanDocument(document: Document) -> Data
}

// 复印功能
protocol Copier {
    func copyDocument(document: Document) -> Document
}

// 只打印,只需要遵守 Printer 协议
class SimplePrinter: Printer {
    func printDocument(document: Document) {
        
    }
}

// 办公室多功能打印机,需要遵守 Printer, Scanner, Copier 协议
class OfficePrinter: Printer, Scanner, Copier {
    func printDocument(document: Document) {
        // 打印
    }
    
    func scanDocument(document: Document) -> Data {
        // 扫描
        return Data()
    }
    
    func copyDocument(document: Document) -> Document {
        // 复印
        return Document()
    }
}

这样,实现这些协议的类只需要关心它们真正需要的功能,从而使代码更加清晰和灵活。

依赖倒置原则 (DIP)

依赖倒置原则强调高层模块不应该依赖低层模块,两者都应该依赖抽象。

概念还是太抽象了,我们来举个例子帮助理解,比如你有个从网络获取数据的类 NetworkFetcher,和一个从数据库获取数据的类 DatabaseFetcher,然后有个提供数据的工具类 DataProvider 来直接依赖前面两个类,这种做法就违背了依赖倒置原则。

正确的做法是将 NetworkFetcherDatabaseFetcher 抽象出一个新的接口给 DataProvider 依赖,我们可以定义一个 DataFetcher 协议,然后让 NetworkFetcherDatabaseFetcher 类实现这个协议:

less 复制代码
protocol DataFetcher {
    func fetchData(completion: @escaping (Data?) -> Void)
}

class NetworkFetcher: DataFetcher {
    func fetchData(completion: @escaping (Data?) -> Void) {
        // 从网络获取数据
    }
}

class DatabaseFetcher: DataFetcher {
    func fetchData(completion: @escaping (Data?) -> Void) {
        // 从数据库获取数据
    }
}

class DataProvider {
    let fetcher: DataFetcher
    
    init(fetcher: DataFetcher) {
        self.fetcher = fetcher
    }
    
    func fetchData() {
        fetcher.fetchData { data in
            // 使用数据
        }
    }
}

这样,DataProvider 类就可以依赖于 DataFetcher 协议,而不是任何具体的数据获取方式,从而提高了代码的灵活性和可测试性。

结论

遵循 SOLID 原则是构建健壮、可维护和灵活的 iOS 应用程序的关键。通过实际的例子,我们可以看到这些原则如何帮助我们改进设计和架构。虽然有些人(或者初学者)可能会觉得遵循这些原则有些麻烦或者困难,但随着经验的不断积累,你就会越来越能感觉到这些原则的重要性,学习更多编程的哲学,这也是你变成大佬的必经之路。

这里每天分享一个 iOS 的新知识,快来关注我吧

本文同步自微信公众号 "iOS新知",每天准时分享一个新知识,这里只是同步,想要及时学到就来关注我吧!

相关推荐
mascon1 小时前
U3D打包IOS的自我总结
ios
名字不要太长 像我这样就好1 小时前
【iOS】继承链
macos·ios·cocoa
karshey2 小时前
【IOS webview】IOS13不支持svelte 样式嵌套
ios
潜龙95272 小时前
第4.3节 iOS App生成追溯关系
macos·ios·cocoa
游戏开发爱好者811 小时前
iOS App 电池消耗管理与优化 提升用户体验的完整指南
android·ios·小程序·https·uni-app·iphone·webview
神策技术社区18 小时前
iOS 全埋点点击事件采集白皮书
大数据·ios·app
wuyoula19 小时前
iOS V2签名网站系统源码/IPA在线签名/全开源版本/亲测
ios
2501_9159184119 小时前
iOS 性能监控工具全解析 选择合适的调试方案提升 App 性能
android·ios·小程序·https·uni-app·iphone·webview
fishycx19 小时前
iOS 构建配置与 AdHoc 打包说明
ios
90后的晨仔20 小时前
ios 集成阿里云的AI智能体报错CocoaPods could not find compatible versions for pod "AUIAICal
ios