引言:为什么SOLID是高质量Swift代码的基础
每位iOS/macOS开发者迟早都会遇到代码变成“意大利面条”的情况:修改一处导致整个应用崩溃,测试变成噩梦。正是在这里,SOLID原则——罗伯特·马丁提出的面向对象设计的五项基本规则——派上了用场。
在本文中,我们将通过Swift示例逐一剖析每个SOLID原则,展示违反它们会导致的问题,并提供现成的解决方案。您将学会编写易于维护、扩展和测试的代码。
1. 单一职责原则(SRP)
理论
SRP指出:一个类应该只有一个引起变化的原因。换句话说,每个类只负责一项功能。
违反SRP(糟糕的代码)
class UserManager { func createUser(name: String, email: String) { // 创建用户 saveToDatabase(user: User(name: name, email: email)) sendWelcomeEmail(to: email) logEvent("User created: \\(name)") } private func saveToDatabase(user: User) { /* ... */ } private func sendWelcomeEmail(to email: String) { /* ... */ } private func logEvent(_ message: String) { /* ... */ }}这里的UserManager负责创建、保存、发送邮件和日志记录——四个引起变化的原因。
修正(良好的代码)
class UserService { private let repository: UserRepository private let emailService: EmailService private let logger: Logger init(repository: UserRepository, emailService: EmailService, logger: Logger) { self.repository = repository self.emailService = emailService self.logger = logger } func createUser(name: String, email: String) { let user = User(name: name, email: email) repository.save(user) emailService.sendWelcome(to: email) logger.log("User created: \\(name)") }}
class UserRepository { func save(_ user: User) { /* 仅负责保存 */ }}class EmailService { func sendWelcome(to email: String) { /* 仅负责发送 */ }}class Logger { func log(_ message: String) { /* 仅负责日志 */ }}现在每个类只有一个职责,从而简化了测试和维护。
2. 开闭原则(OCP)
理论
类应该对扩展开放,但对修改关闭。通过继承或协议添加新功能,而不修改现有代码。
违反OCP
class PaymentProcessor { func process(payment: Any, type: String) { if type == "card" { // 处理信用卡
} else if type == "paypal" { // 处理PayPal
} // 添加新类型时——需要修改此类
}}通过协议修正
protocol PaymentMethod { func process(amount: Double)}
class CardPayment: PaymentMethod { func process(amount: Double) { /* 处理信用卡 */ }}
class PayPalPayment: PaymentMethod { func process(amount: Double) { /* 处理PayPal */ }}
class PaymentProcessor { func process(payment: PaymentMethod, amount: Double) { payment.process(amount: amount) }}
// 添加新类型而不修改现有代码
class ApplePayPayment: PaymentMethod { func process(amount: Double) { /* 处理Apple Pay */ }}现在要添加新的支付方式,只需创建一个实现PaymentMethod协议的新类即可。