Swift中的SOLID原则:iOS/macOS理论与实践

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:为什么 SOLID 对 Swift 开发者很重要



iOS 和 macOS 开发不仅需要掌握框架知识,还需要具备构建可维护、可测试、可扩展架构的能力。这正是 SOLID 原则 发挥作用的地方——这是由 Robert Martin(Bob 大叔)提出的面向对象设计的五项基本规则。



在本文中,我们将通过 Swift 代码示例逐一解析 SOLID 的五个原则,展示典型的反模式,并提供正确的解决方案。阅读后,您将能够编写易于维护、扩展和测试的代码。



1. Single Responsibility Principle (SRP) — 单一职责原则



定义: 一个类应该只有一个引起它变化的原因。换句话说,每个模块只负责一项功能。



问题:上帝类



考虑一个 iOS 开发中的典型例子——UserManager 类,它做了太多事情:



class UserManager {    func fetchUser() -> User { /* 网络请求 */ }    func saveUserToDatabase(_ user: User) { /* 操作 CoreData */ }    func formatUserDisplayName(_ user: User) -> String { /* 格式化 */ }    func sendWelcomeEmail(to user: User) { /* 发送邮件 */ }}


这里,该类同时负责网络请求、数据库操作、UI 格式化和邮件发送。其中任何一个方面的更改都会导致 UserManager 的修改。



解决方案:职责分离



class UserNetworkService {    func fetchUser() -> User { /* 仅网络请求 */ }}

class UserDatabaseService { func saveUser(_ user: User) { /* 仅数据库操作 */ }}

class UserFormatter { func displayName(for user: User) -> String { /* 仅格式化 */ }}

class EmailService { func sendWelcome(to user: User) { /* 仅发送邮件 */ }}


现在每个类都有明确的单一职责,从而简化了测试和修改。



2. Open/Closed Principle (OCP) — 开闭原则



定义: 软件实体应对扩展开放,对修改关闭。



问题:僵硬的逻辑



假设我们有一个计算折扣的类:



class DiscountCalculator {    func calculateDiscount(for order: Order, customerType: String) -> Double {        if customerType == "regular" {            return order.total * 0.05        } else if customerType == "premium" {            return order.total * 0.1        } else if customerType == "vip" {            return order.total * 0.2        }        return 0    }}


当添加新的客户类型(如 gold)时,必须修改现有类,这违反了 OCP。



解决方案:协议与多态



protocol DiscountStrategy {    func discount(for order: Order) -> Double}

struct RegularDiscount: DiscountStrategy { func discount(for order: Order) -> Double { order.total * 0.05 }}

struct PremiumDiscount: DiscountStrategy { func discount(for order: Order) -> Double { order.total * 0.1 }}

struct VIPDiscount: DiscountStrategy { func discount(for order: Order) -> Double { order.total * 0.2 }}

class DiscountCalculator { func calculateDiscount(for order: Order, using strategy: DiscountStrategy) -> Double { return strategy.discount(for: order) }}


现在,要添加新的折扣,只需创建一个实现 DiscountStrategy 协议的新结构体,而无需修改 DiscountCalculator。



3. Liskov Substitution Principle (LSP) — 里氏替换原则



定义:

博客

书籍推荐