Swift 中的 Clean Code:原则与示例
Clean Code(整洁代码)不仅仅是一个流行术语,更是一种开发哲学,它直接影响功能开发速度、Bug 数量以及工作乐趣。对于从事 iOS 和 macOS 应用程序开发的 Swift 开发者来说,编写易于阅读和维护的代码尤为重要,因为项目会持续多年,团队也会不断变化。本文将解析 Clean Code 在 Swift 中的主要原则,并展示具体示例。
1. 命名:使用领域语言
正确的命名是可读代码的基础。变量、函数和类的名称应回答“是什么?”和“为什么?”的问题。避免使用缩写和单字母名称(短循环中的 i 除外)。
反面示例:
func calc(a: Int, b: Int) -> Int { return a * b + 10}正面示例:
func calculateTotalPriceWithShipping(itemPrice: Int, shippingCost: Int) -> Int { return itemPrice + shippingCost}对于布尔变量,使用前缀 is、has、should:
var isUserLoggedIn: Bool = falsevar hasCompletedOnboarding: Bool = true类名应为名词(UserManager、NetworkService),函数名应为动词或动词短语(fetchData()、validateEmail())。
2. 函数:短小且职责单一
每个函数应只做一件事,并且做好。理想的函数长度为 10-20 行。如果函数超过 30 行,请将其拆分为更小的函数。
反面示例:一个函数同时进行验证、保存和发送通知。
func processUser(_ user: User) { // 验证 guard !user.name.isEmpty else { return } guard user.age > 18 else { return } // 保存 CoreDataManager.shared.save(user) // 通知 NotificationCenter.default.post(name: .userDidRegister, object: nil)}正面示例:拆分为三个独立的函数。
func processUser(_ user: User) { guard isValid(user) else { return } saveUser(user) notifyUserRegistration()}
private func isValid(_ user: User) -> Bool { return !user.name.isEmpty && user.age > 18}
private func saveUser(_ user: User) { CoreDataManager.shared.save(user)}
private func notifyUserRegistration() { NotificationCenter.default.post(name: .userDidRegister, object: nil)}同时,避免参数过多。如果参数超过三个,请将它们合并到一个结构体中。
struct SearchConfig { let query: String let category: String? let page: Int let pageSize: Int}
func search(with config: SearchConfig) -> [Result] { ... }3. Swift 中的 SOLID 原则:实践示例
SOLID 原则是面向对象语言中整洁代码的基石。下面通过 Swift 示例介绍两个关键原则。
单一职责原则 (SRP)
一个类应该只有一个引起变化的原因。不要将网络逻辑和 UI 逻辑混在一起。
// 违反 SRPclass UserViewController: UIViewController { func fetchUser() { URLSession.shared.dataTask(with: URL(string: "...")!) { ... } } func updateUI() { ... }}
// 修正后class UserNetworkService { func fetchUser(completion: (User) -> Void) { ... }}
class UserViewController: UIViewController { let networkService = UserNetworkService() func loadUser() { networkService.fetchUser { [weak self] user in DispatchQueue.main.async { self?.updateU
```