常见的设计模式

2025-07-29  本文已影响0人  大成小栈

在 iOS 开发中,设计模式是解决常见问题的标准化方案。
以下是 5 种常用设计模式的 Swift 示例:


1. 单例模式 (Singleton)

目的:确保一个类只有一个实例,并提供全局访问点
应用场景:配置管理、日志记录器、网络管理器

class NetworkManager {
    static let shared = NetworkManager() // 单例实例
    private init() {} // 禁止外部初始化
    
    func fetchData() {
        print("Fetching data...")
    }
}

// 使用
NetworkManager.shared.fetchData()

2. 委托模式 (Delegate)

目的:允许对象间通信(一对一的回调机制)
应用场景:UITableView 事件处理、自定义控件回调

protocol ButtonDelegate: AnyObject {
    func didTapButton()
}

class CustomButton {
    weak var delegate: ButtonDelegate? // 弱引用避免循环引用
    
    func userTapped() {
        delegate?.didTapButton()
    }
}

class ViewController: ButtonDelegate {
    let button = CustomButton()
    
    func setup() {
        button.delegate = self
    }
    
    func didTapButton() {
        print("Button tapped!")
    }
}

3. 观察者模式 (Observer)

目的:实现一对多的依赖关系(状态变化时通知多个对象)
应用场景:数据模型更新通知 UI、KVO

// 使用 NotificationCenter
extension Notification.Name {
    static let dataUpdated = Notification.Name("dataUpdated")
}

class DataModel {
    func updateData() {
        NotificationCenter.default.post(name: .dataUpdated, object: nil)
    }
}

class ViewController {
    init() {
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(handleUpdate),
            name: .dataUpdated,
            object: nil
        )
    }
    
    @objc func handleUpdate() {
        print("Data updated!")
    }
}

4. 工厂模式 (Factory)

目的:将对象创建逻辑封装,客户端无需知道具体类
应用场景:根据条件创建不同子类对象

protocol Animal {
    func speak()
}

class Dog: Animal {
    func speak() { print("Woof!") }
}

class Cat: Animal {
    func speak() { print("Meow!") }
}

class AnimalFactory {
    enum AnimalType { case dog, cat }
    
    func createAnimal(type: AnimalType) -> Animal {
        switch type {
        case .dog: return Dog()
        case .cat: return Cat()
        }
    }
}

// 使用
let factory = AnimalFactory()
let dog = factory.createAnimal(type: .dog)
dog.speak() // 输出: Woof!

5. MVVM 模式 (Model-View-ViewModel)

目的:分离业务逻辑和视图逻辑(非原生但最常用)
应用场景:数据绑定驱动 UI 更新

// Model
struct User {
    var name: String
}

// ViewModel
class UserViewModel {
    var user: User {
        didSet { onUpdate?() }
    }
    var onUpdate: (() -> Void)? // 数据更新回调
    
    init(user: User) {
        self.user = user
    }
    
    func updateName(_ name: String) {
        user.name = name
    }
}

// View (ViewController)
class ProfileViewController: UIViewController {
    var viewModel: UserViewModel! {
        didSet {
            viewModel.onUpdate = { [weak self] in
                self?.updateUI()
            }
        }
    }
    
    func updateUI() {
        print("Name updated to: \(viewModel.user.name)")
    }
    
    // 模拟用户操作
    func userChangedName() {
        viewModel.updateName("Alice")
    }
}

关键总结

模式 核心思想 iOS 典型应用
单例 全局唯一实例 FileManager.default
委托 协议回调解耦 UITableViewDelegate
观察者 一对多通知 NotificationCenter
工厂 封装对象创建过程 UICollectionViewLayout
MVVM 数据绑定驱动 UI SwiftUI/Combine 的基石

这些模式可单独或组合使用,有效提升代码的可维护性、可测试性和复用性。


其他不常用的设计模式如下:

6. 责任链模式 (Chain of Responsibility)

目的:将请求沿着处理链传递,直到有对象处理它
应用场景:事件处理、权限验证、日志过滤

protocol Handler: AnyObject {
    var next: Handler? { get set }
    func handle(request: Int)
}

class ConcreteHandlerA: Handler {
    var next: Handler?
    func handle(request: Int) {
        if request <= 10 {
            print("Handler A processing request \(request)")
        } else {
            next?.handle(request: request)
        }
    }
}

class ConcreteHandlerB: Handler {
    var next: Handler?
    func handle(request: Int) {
        if request <= 20 {
            print("Handler B processing request \(request)")
        } else {
            print("No handler for request \(request)")
        }
    }
}

// 使用
let handlerA = ConcreteHandlerA()
let handlerB = ConcreteHandlerB()
handlerA.next = handlerB

handlerA.handle(request: 5)  // Handler A processing request 5
handlerA.handle(request: 15) // Handler B processing request 15
handlerA.handle(request: 25) // No handler for request 25

7. 建造者模式 (Builder)

目的:分离复杂对象的构建与表示
应用场景:创建配置复杂的对象(如URLRequest、UIAlertController)

class Pizza {
    var size: Int = 0
    var cheese: Bool = false
    var pepperoni: Bool = false
    var bacon: Bool = false
    
    class Builder {
        private var pizza = Pizza()
        
        func setSize(_ size: Int) -> Builder {
            pizza.size = size
            return self
        }
        
        func addCheese() -> Builder {
            pizza.cheese = true
            return self
        }
        
        func addPepperoni() -> Builder {
            pizza.pepperoni = true
            return self
        }
        
        func addBacon() -> Builder {
            pizza.bacon = true
            return self
        }
        
        func build() -> Pizza {
            return pizza
        }
    }
}

// 使用
let pizza = Pizza.Builder()
    .setSize(12)
    .addCheese()
    .addBacon()
    .build()

print("Size: \(pizza.size), Cheese: \(pizza.cheese), Bacon: \(pizza.bacon)")
// 输出:Size: 12, Cheese: true, Bacon: true

8. 原型模式 (Prototype)

目的:通过复制现有对象创建新对象
应用场景:对象创建成本高或需要隔离对象创建过程

class Document: NSCopying {
    var title: String
    var content: String
    
    init(title: String, content: String) {
        self.title = title
        self.content = content
    }
    
    func copy(with zone: NSZone? = nil) -> Any {
        return Document(title: title, content: content)
    }
}

// 使用
let original = Document(title: "Report", content: "Important data")
let copy = original.copy() as! Document
copy.title = "Copy Report"

print(original.title) // "Report"
print(copy.title)    // "Copy Report"

9. 备忘录模式 (Memento)

目的:捕获并外部化对象状态以便后续恢复
应用场景:撤销/重做功能、状态保存

// 发起人
class TextEditor {
    private var text: String = ""
    
    func write(_ newText: String) {
        text += newText
    }
    
    func show() {
        print("Current text: \(text)")
    }
    
    func save() -> Memento {
        return TextMemento(text: text)
    }
    
    func restore(from memento: Memento) {
        guard let m = memento as? TextMemento else { return }
        text = m.text
    }
}

// 备忘录协议
protocol Memento {}

// 具体备忘录
class TextMemento: Memento {
    let text: String
    init(text: String) {
        self.text = text
    }
}

// 使用
let editor = TextEditor()
editor.write("Hello ")
let save1 = editor.save()

editor.write("World!")
editor.show() // Current text: Hello World!

editor.restore(from: save1)
editor.show() // Current text: Hello 

10. 命令模式 (Command)

目的:将请求封装为对象,支持请求排队、日志记录和撤销
应用场景:操作队列、事务管理、遥控器功能

protocol Command {
    func execute()
    func undo()
}

class Light {
    func on() { print("Light is ON") }
    func off() { print("Light is OFF") }
}

class LightOnCommand: Command {
    private let light: Light
    
    init(light: Light) {
        self.light = light
    }
    
    func execute() {
        light.on()
    }
    
    func undo() {
        light.off()
    }
}

class RemoteControl {
    private var command: Command?
    
    func setCommand(_ command: Command) {
        self.command = command
    }
    
    func pressButton() {
        command?.execute()
    }
    
    func pressUndo() {
        command?.undo()
    }
}

// 使用
let light = Light()
let lightOn = LightOnCommand(light: light)
let remote = RemoteControl()

remote.setCommand(lightOn)
remote.pressButton()  // Light is ON
remote.pressUndo()    // Light is OFF

设计模式对比表

模式 核心思想 典型应用场景
责任链 请求沿处理链传递 权限验证、事件过滤
建造者 分步构建复杂对象 配置复杂对象(URLRequest)
原型 克隆已有对象创建新实例 高成本对象创建
备忘录 捕获/恢复对象状态 撤销操作、状态保存
命令 封装操作为对象 操作队列、事务管理
单例 全局唯一实例 共享资源管理
委托 协议回调解耦 UITableView 事件
观察者 一对多状态通知 数据绑定
工厂 封装对象创建逻辑 多态对象创建
MVVM 数据绑定驱动UI 响应式界面

这些设计模式在iOS开发中相互配合使用,能有效解决以下问题:

  1. 降低耦合度(委托、观察者)
  2. 简化复杂对象创建(建造者、工厂)
  3. 状态管理(备忘录、命令)
  4. 行为封装(责任链、命令)
  5. 对象复用(原型、单例)

实际开发中通常会组合使用多种模式,例如在MVVM架构中使用委托进行组件通信,配合工厂创建ViewModel等。

上一篇 下一篇

猜你喜欢

热点阅读