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不是教条,而是服务于代码质量的工具。

相关推荐
HarderCoder1 天前
Swift 中的不透明类型与装箱协议类型:概念、区别与实践
swift
HarderCoder1 天前
Swift 泛型深度指南 ——从“交换两个值”到“通用容器”的代码复用之路
swift
东坡肘子1 天前
惊险但幸运,两次!| 肘子的 Swift 周报 #0109
人工智能·swiftui·swift
胖虎11 天前
Swift项目生成Framework流程以及与OC的区别
framework·swift·1024程序员节·swift framework
songgeb2 天前
What Auto Layout Doesn’t Allow
swift
YGGP2 天前
【Swift】LeetCode 240.搜索二维矩阵 II
swift
YGGP2 天前
【Swift】LeetCode 73. 矩阵置零
swift
非专业程序员Ping4 天前
HarfBuzz 实战:五大核心API 实例详解【附iOS/Swift实战示例】
android·ios·swift
Swift社区5 天前
LeetCode 409 - 最长回文串 | Swift 实战题解
算法·leetcode·swift
YGGP7 天前
【Swift】LeetCode 54. 螺旋矩阵
swift