iOS开发中常用的设计模式原理以及使用场景代码示例

413 阅读5分钟

在 iOS 开发中,设计模式是提高代码可维护性和可扩展性的重要手段。以下是 iOS 开发中最常用的 7 种设计模式详解:

一、MVC 模式(Model-View-Controller)

原理

苹果官方推荐模式,将应用分为:

  • Model:数据层
  • View:界面层
  • Controller:业务逻辑层

优缺点

✅ 优点:

  • 职责分离明确
  • 官方框架原生支持
  • 学习成本低

❌ 缺点:

  • Controller 容易臃肿(Massive View Controller)
  • View 和 Model 存在耦合

使用场景

小型项目或需要快速开发的场景

<代码示例>

// OC 实现
// Model
@interface User : NSObject
@property (nonatomic, copy) NSString *name;
@end

// View
@interface ProfileView : UIView
- (void)updateName:(NSString *)name;
@end

// Controller
@interface ProfileViewController : UIViewController
@property (strong, nonatomic) User *user;
@property (strong, nonatomic) ProfileView *profileView;
@end

@implementation
- (void)viewDidLoad {
    [self.profileView updateName:self.user.name];
}
@end
// Swift 实现
// Model
struct User {
    let name: String
}

// View
class ProfileView: UIView {
    func updateName(_ name: String) {
        // 更新界面
    }
}

// Controller
class ProfileViewController: UIViewController {
    var user: User!
    var profileView: ProfileView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        profileView.updateName(user.name)
    }
}

二、MVVM 模式(Model-View-ViewModel)

原理

  • ViewModel:处理业务逻辑
  • View:界面展示
  • 数据绑定实现自动更新

优缺点

✅ 优点:

  • 更好的职责分离
  • 便于单元测试
  • 减少 Controller 体积

❌ 缺点:

  • 数据绑定增加复杂度
  • 需要额外学习响应式编程

使用场景

中大型项目,需要复杂业务逻辑的场景

<代码示例>

// Swift 实现(使用 Combine)
class UserViewModel {
    @Published var userName: String = ""
    
    func loadUser() {
        // 网络请求...
        userName = "John"
    }
}

class ProfileViewController: UIViewController {
    private var viewModel = UserViewModel()
    private var cancellables = Set<AnyCancellable>()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        viewModel.$userName
            .sink { [weak self] name in
                self?.updateUI(name: name)
            }
            .store(in: &cancellables)
    }
    
    private func updateUI(name: String) {
        // 更新界面
    }
}
// OC 实现(使用 KVO)
// ViewModel
@interface UserViewModel : NSObject
@property (nonatomic, strong) NSString *userName;
- (void)loadUser;
@end

// Controller
@interface ProfileViewController : UIViewController
@property (strong, nonatomic) UserViewModel *viewModel;
@end

@implementation
- (void)viewDidLoad {
    [self.viewModel addObserver:self 
                     forKeyPath:@"userName"
                        options:NSKeyValueObservingOptionNew
                        context:nil];
}

- (void)observeValueForKeyPath:(NSString *)keyPath 
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context {
    if ([keyPath isEqualToString:@"userName"]) {
        [self updateUIWithName:change[NSKeyValueChangeNewKey]];
    }
}
@end

三、单例模式(Singleton)

原理

确保类只有一个实例,并提供全局访问点

优缺点

✅ 优点:

  • 全局访问方便
  • 节省资源

❌ 缺点:

  • 难以单元测试
  • 可能造成全局状态污染

使用场景

需要全局唯一实例的场景(如日志管理、网络监控)

<代码示例>

// Swift 实现
class NetworkManager {
    static let shared = NetworkManager()
    private init() {}
    
    func request() {
        // 网络请求...
    }
}

// 使用
NetworkManager.shared.request()
// OC 实现
@interface NetworkManager : NSObject
+ (instancetype)shared;
@end

@implementation
+ (instancetype)shared {
    static NetworkManager *instance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[self alloc] init];
    });
    return instance;
}
@end

四、观察者模式(Observer)

原理

对象间定义一对多的依赖关系,当一个对象状态改变时,所有依赖者都会收到通知

优缺点

✅ 优点:

  • 解耦观察者与被观察者
  • 支持广播通信

❌ 缺点:

  • 内存泄漏风险(未及时移除观察者)
  • 调试困难

使用场景

需要实现事件通知机制的场景

<代码示例>

// Swift 使用 NotificationCenter
let notificationName = Notification.Name("DataUpdated")

// 发送通知
NotificationCenter.default.post(name: notificationName, object: nil)

// 接收通知
NotificationCenter.default.addObserver(
    self,
    selector: #selector(handleNotification),
    name: notificationName,
    object: nil
)
// OC 实现 KVO
@interface DataModel : NSObject
@property (nonatomic, strong) NSString *data;
@end

// 观察者
[dataModel addObserver:self
            forKeyPath:@"data"
               options:NSKeyValueObservingOptionNew
               context:nil];

五、工厂模式(Factory)

原理

通过工厂类创建对象,而不是直接实例化具体类

优缺点

✅ 优点:

  • 解耦对象创建和使用
  • 方便扩展新产品

❌ 缺点:

  • 增加代码复杂度
  • 需要设计良好的继承体系

使用场景

需要灵活创建对象的场景(如不同主题切换)

<代码示例>

// Swift 实现
protocol Button {
    func render()
}

class iOSButton: Button {
    func render() { print("iOS Style Button") }
}

class AndroidButton: Button {
    func render() { print("Material Design Button") }
}

enum Platform {
    case iOS, android
}

class ButtonFactory {
    static func createButton(for platform: Platform) -> Button {
        switch platform {
        case .iOS: return iOSButton()
        case .android: return AndroidButton()
        }
    }
}

// 使用
let button = ButtonFactory.createButton(for: .iOS)
// OC 实现
@protocol Button <NSObject>
- (void)render;
@end

@interface iOSButton : NSObject <Button>
@end
@implementation
- (void)render { NSLog(@"iOS Style Button"); }
@end

typedef NS_ENUM(NSUInteger, Platform) {
    PlatformiOS,
    PlatformAndroid
};

@interface ButtonFactory : NSObject
+ (id<Button>)createButtonForPlatform:(Platform)platform;
@end

@implementation
+ (id<Button>)createButtonForPlatform:(Platform)platform {
    switch (platform) {
        case PlatformiOS: return [iOSButton new];
        case PlatformAndroid: return [AndroidButton new];
    }
}
@end

六、代理模式(Delegate)

原理

定义一个协议,委托方通过协议与代理方通信

优缺点

✅ 优点:

  • 解耦委托方和代理方
  • 支持多个代理

❌ 缺点:

  • 协议方法需要逐层传递
  • 可能产生长链式调用

使用场景

需要回调机制的场景(如 UITableView 的点击事件)

<代码示例>

// Swift 实现
protocol ImageDownloaderDelegate: AnyObject {
    func didFinishDownloading(image: UIImage)
}

class ImageDownloader {
    weak var delegate: ImageDownloaderDelegate?
    
    func download() {
        // 下载完成...
        delegate?.didFinishDownloading(image: UIImage())
    }
}

class ViewController: ImageDownloaderDelegate {
    let downloader = ImageDownloader()
    
    init() {
        downloader.delegate = self
    }
    
    func didFinishDownloading(image: UIImage) {
        // 处理图片
    }
}
// OC 实现
@protocol ImageDownloaderDelegate <NSObject>
- (void)didFinishDownloadingImage:(UIImage *)image;
@end

@interface ImageDownloader : NSObject
@property (weak) id<ImageDownloaderDelegate> delegate;
- (void)download;
@end

@implementation
- (void)download {
    // 下载完成...
    [self.delegate didFinishDownloadingImage:[UIImage new]];
}
@end

七、策略模式(Strategy)

原理

定义算法族,使算法可以互相替换

优缺点

✅ 优点:

  • 避免多重条件语句
  • 方便扩展新算法

❌ 缺点:

  • 增加对象数量
  • 需要客户端了解不同策略

使用场景

需要动态切换算法的场景(如排序算法选择)

<代码示例>

// Swift 实现
protocol PaymentStrategy {
    func pay(amount: Double) -> Bool
}

class Alipay: PaymentStrategy {
    func pay(amount: Double) -> Bool {
        print("支付宝支付")
        return true
    }
}

class WechatPay: PaymentStrategy {
    func pay(amount: Double) -> Bool {
        print("微信支付")
        return true
    }
}

class PaymentContext {
    private var strategy: PaymentStrategy
    
    init(strategy: PaymentStrategy) {
        self.strategy = strategy
    }
    
    func executePayment(amount: Double) -> Bool {
        return strategy.pay(amount: amount)
    }
}

// 使用
let context = PaymentContext(strategy: Alipay())
context.executePayment(amount: 100)
// OC 实现
@protocol PaymentStrategy <NSObject>
- (BOOL)payAmount:(CGFloat)amount;
@end

@interface Alipay : NSObject <PaymentStrategy>
@end
@implementation
- (BOOL)payAmount:(CGFloat)amount {
    NSLog(@"支付宝支付");
    return YES;
}
@end

@interface PaymentContext : NSObject
- (instancetype)initWithStrategy:(id<PaymentStrategy>)strategy;
- (BOOL)executePayment:(CGFloat)amount;
@end

@interface PaymentContext ()
@property (strong) id<PaymentStrategy> strategy;
@end

@implementation
- (BOOL)executePayment:(CGFloat)amount {
    return [self.strategy payAmount:amount];
}
@end

总结建议

  1. 简单场景优先使用 MVC
  2. 复杂业务逻辑推荐 MVVM + 响应式编程
  3. 全局服务使用单例但要严格控制
  4. 组件通信优先选择代理模式
  5. 动态行为切换使用策略模式
  6. 对象创建复杂时采用工厂模式
  7. 跨模块通知使用观察者模式

每种模式都有其适用场景,实际开发中通常会组合使用多种设计模式。建议根据具体需求选择最合适的模式,避免为了使用模式而过度设计。