ByAI:使用DRY原则编写干净可复用的Swift代码

什么是DRY?

DRY代表:不要重复你自己(Don't Repeat Yourself)

这个编程原则鼓励避免逻辑重复,通过函数/扩展/泛型等Swift工具复用代码。为什么?因为重复代码更难维护,增加bug风险,使代码库混乱难读。让我们通过实际示例看看如何实践DRY。


问题案例

典型的新手错误:

swift 复制代码
func greetUser(name: String) {
    print("Hello, (name)!")
}

func welcomeUser(name: String) {
    print("Hello, (name)!")
    print("Welcome to our app.")
}

这两个函数有重复逻辑。当需要修改问候语时,必须在两处同时修改,这违反了DRY。


DRY改造版

swift 复制代码
func greet(name: String) {
    print("Hello, (name)!")
}

func welcomeUser(name: String) {
    greet(name: name)
    print("Welcome to our app.")
}

现在问候逻辑集中在一处,修改时只需改一个函数,代码更易维护。


Swift中的DRY工具

1. 函数封装

改造前

swift 复制代码
print("Fetching data...")
// 业务逻辑
print("Fetching data...")

改造后

swift 复制代码
func showLoadingMessage() {
    print("Fetching data...")
}

showLoadingMessage()
// 业务逻辑
showLoadingMessage()

2. 扩展(Extensions)

日期格式化改造前

swift 复制代码
let formatter = DateFormatter()
formatter.dateStyle = .medium
let dateString = formatter.string(from: Date())

改造后

swift 复制代码
extension Date {
    /// 格式化为本地化中等样式,如"2025年6月5日"
    func formattedMedium() -> String {
        self.formatted(.dateTime.year().month().day())
    }
}

// 使用:
let dateString = Date().formattedMedium()

3. 计算属性

年龄判断改造前

swift 复制代码
struct User { let age: Int }

if user.age > 18 { /* 成人逻辑 */ }
guard user.age > 18 else { return }

改造后

swift 复制代码
struct User {
    let age: Int
    var isAdult: Bool { age > 18 }
}

if user.isAdult { /* 成人逻辑 */ }
guard user.isAdult else { return }

4. 泛型(Generics)

数组打印改造前

swift 复制代码
func printIntArray(_ array: [Int]) {
    array.forEach { print($0) }
}

func printStringArray(_ array: [String]) {
    array.forEach { print($0) }
}

改造后

swift 复制代码
func printArray<T>(_ array: [T]) {
    array.forEach { print($0) }
}

printArray([1, 2, 3])     // 打印Int
printArray(["a", "b", "c"]) // 打印String

5. 协议扩展

日志功能改造前

swift 复制代码
class UserViewModel {
    func log() { print("UserViewModel log") }
}

class ProductViewModel {
    func log() { print("ProductViewModel log") }
}

改造后

swift 复制代码
protocol Loggable {
    func log()
}

extension Loggable {
    func log() {
        print("(Self.self) log")
    }
}

class UserViewModel: Loggable {}
class ProductViewModel: Loggable {}

userVM.log() // 输出:UserViewModel log

何时应该避免DRY?

DRY也有适用边界:

  1. 如果合并代码会降低可读性
  2. 当相似逻辑可能独立变化时
  3. 少量重复优于过度设计

总结

工具 适用场景 示例收益
函数封装 重复代码段 集中修改点
扩展 添加通用功能 日期格式化复用
计算属性 频繁使用的属性判断 业务规则集中管理
泛型 类型无关的通用操作 统一容器处理逻辑
协议扩展 多类型共享默认实现 减少样板代码

核心原则

✅ 识别重复模式后抽象

✅ 优先使用Swift类型系统

✅ 在简洁性和灵活性间平衡

通过合理运用这些技巧,可以使代码库更健壮、更易维护,同时提升开发效率。记住,DRY不是教条,而是服务于代码质量的工具。

相关推荐
初级代码游戏2 天前
iOS开发 SwiftUI 14:ScrollView 滚动视图
ios·swiftui·swift
初级代码游戏3 天前
iOS开发 SwitftUI 13:提示、弹窗、上下文菜单
ios·swiftui·swift·弹窗·消息框
zhyongrui3 天前
托盘删除手势与引导体验修复:滚动冲突、画布消失动画、气泡边框
ios·性能优化·swiftui·swift
zhangfeng11333 天前
CSDN星图 支持大模型微调 trl axolotl Unsloth 趋动云 LLaMA-Factory Unsloth ms-swift 模型训练
服务器·人工智能·swift
zhyongrui4 天前
SnipTrip 发热优化实战:从 60Hz 到 30Hz 的性能之旅
ios·swiftui·swift
大熊猫侯佩4 天前
Neo-Cupertino 档案:撕开 Actor 的伪装,回归 Non-Sendable 的暴力美学
swift·observable·actor·concurrency·sendable·nonsendable·data race
2501_915921436 天前
在没有源码的前提下,怎么对 Swift 做混淆,IPA 混淆
android·开发语言·ios·小程序·uni-app·iphone·swift
00后程序员张6 天前
对比 Ipa Guard 与 Swift Shield 在 iOS 应用安全处理中的使用差异
android·开发语言·ios·小程序·uni-app·iphone·swift
大熊猫侯佩7 天前
星际穿越:SwiftUI 如何让 ForEach 遍历异构数据(Heterogeneous)集合
swiftui·swift·遍历·foreach·any·异构集合·heterogeneous
hjs_deeplearning7 天前
认知篇#15:ms-swift微调中gradient_accumulation_steps和warmup_ratio等参数的意义与设置
开发语言·人工智能·机器学习·swift·vlm