Swift中的SOLID原则:高级iOS开发者的理论与实践

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

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

开始课程

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

在iOS开发领域,创建可维护且可扩展的代码是一项关键任务。由Robert Martin提出的SOLID原则仍然是软件架构的黄金标准。在高级水平上掌握Swift中的这些原则,不仅能让你编写干净的代码,还能构建灵活、能抵御需求变更的系统。在本文中,我们将结合Swift示例,针对iOS/macOS开发者的实际任务,逐一解析每个原则。



1. Swift中的单一职责原则(SRP)

理论:每个类或结构体应该只有一个变更原因。在实践中,这意味着一个模块只负责一个明确定义的任务。



问题:过载的ViewController

在UIKit中,经常遇到同时管理UI、处理网络请求和保存数据的控制器。这违反了SRP。

// ❌ 违反SRPclass UserViewController: UIViewController {    @IBOutlet weak var tableView: UITableView!    private var users: [User] = []

override func viewDidLoad() { super.viewDidLoad() fetchUsers() }

private func fetchUsers() { // 网络请求 URLSession.shared.dataTask(with: URL(string: "https://api.example.com/users")!) { data, _, _ in // 解析JSON // 保存到Core Data DispatchQueue.main.async { self.tableView.reloadData() } }.resume() }}


解决方案:分离职责

将数据处理和网络请求逻辑提取到独立的服务中。

// ✅ SRP:独立的用户服务protocol UserServiceProtocol {    func fetchUsers(completion: @escaping (Result<[User], Error>) -> Void)}

class UserService: UserServiceProtocol { func fetchUsers(completion: @escaping (Result<[User], Error>) -> Void) { // 网络请求逻辑 }}

// ✅ SRP:独立的Core Data管理器class CoreDataManager { func saveUsers(_ users: [User]) { // 保存到Core Data }}

// ✅ SRP:ViewController仅管理UIclass UserViewController: UIViewController { private let userService: UserServiceProtocol private let coreDataManager: CoreDataManager

init(userService: UserServiceProtocol, coreDataManager: CoreDataManager) { self.userService = userService self.coreDataManager = coreDataManager super.init(nibName: nil, bundle: nil) }

override func viewDidLoad() { super.viewDidLoad() loadUsers() }

private func loadUsers() { userService.fetchUsers { [weak self] result in switch result { case .success(let users): self?.coreDataManager.saveUsers(users) self?.updateUI(with: users) case .failure(let error): self?.showError(error) } } }}


2. 开闭原则(OCP)与Swift协议

理论:软件实体(类、模块)应该对扩展开放,对修改关闭。在Swift中,这通过协议和继承来实现。



示例:通知系统

// ❌ 违反OCP:添加新通知类型时需要修改switch语句class NotificationSender {    func send(_ notification: Notification, type: String) {        switch type {        case "email":            // 发送邮件        case "push":            // 发送推送        default:            break        }    }}

// ✅ OCP:使用协议protocol NotificationChannel { func send(_ notification: Notification)}

class EmailChannel: NotificationChannel { func send(_ notification: Notification)

博客

书籍推荐