iOS 架构实战 | 组合模式、策略模式与工厂模式

在 iOS 开发中,我们经常会遇以下问题:

  • 模块需要复用或灵活组合
  • 行为需要动态切换,例如支付方式或广告策略
  • 对象创建复杂,业务方不希望关心底层实现

针对这些问题,本文通过 组合模式(Composition)策略模式(Strategy)工厂模式(Factory),讲解如何在实际项目中应用,并结合系统 API / 三方库示例。

一.组合模式(Composition)

场景背景

业务数据存储模块通常只会有一个底层数据库(如 SQLite),但为了以后替换为 CoreData / Realm 时能无痛切换,可以使用组合模式封装底层实现。

设计原理

组合模式通过 内部组合对象 来复用功能,而不是继承。业务方只调用统一接口,无需感知底层具体实现。

代码示例

@protocol EVStorageProtocol <NSObject>
- (void)saveObject:(id)object forKey:(NSString *)key;
- (nullable id)loadObjectForKey:(NSString *)key;
- (void)deleteObjectForKey:(NSString *)key;
@end

@interface EVStorageManager : NSObject
+ (instancetype)shared;
- (void)saveObject:(id)object forKey:(NSString *)key;
- (nullable id)loadObjectForKey:(NSString *)key;
- (void)deleteObjectForKey:(NSString *)key;
@end

@implementation EVStorageManager {
    id<EVStorageProtocol> _storage; // 内部组合对象
}

+ (instancetype)shared {
    static EVStorageManager *instance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[EVStorageManager alloc] initPrivate];
    });
    return instance;
}

- (instancetype)initPrivate {
    if (self = [super init]) {
        // 内部组合固定数据库实现(例如 SQLite)
        _storage = [[EVSQLiteStorage alloc] init];
    }
    return self;
}

- (void)saveObject:(id)object forKey:(NSString *)key { [_storage saveObject:object forKey:key]; }
- (nullable id)loadObjectForKey:(NSString *)key { return [_storage loadObjectForKey:key]; }
- (void)deleteObjectForKey:(NSString *)key { [_storage deleteObjectForKey:key]; }
@end

系统 API / 三方库示例

  • UIViewController 内部组合 UIViewUINavigationItem 等对象,实现界面功能
  • MMKV 内部组合内存缓存 + 磁盘缓存,业务方调用无感

分析

  • 业务方调用统一接口,无需关心底层实现
  • 将来替换数据库,只需修改组合对象,不影响业务层
  • 组合模式是策略模式和工厂模式的基础

二、策略模式(Strategy)

场景背景

支付模块需要支持 微信支付 / 支付宝 / Apple Pay,业务方只关心“付多少钱”,不关心具体实现。数据库切换场景也属于策略模式。

设计原理

策略模式将行为封装成策略对象,在运行时动态选择,业务方只调用统一接口。

代码示例

@protocol EVPaymentStrategy <NSObject>
- (void)payWithAmount:(double)amount;
@end

@interface EVWeChatPayStrategy : NSObject <EVPaymentStrategy> @end
@interface EVAlipayPayStrategy : NSObject <EVPaymentStrategy> @end
@interface EVApplePayStrategy : NSObject <EVPaymentStrategy> @end

@interface EVPaymentManager : NSObject
- (void)payWithAmount:(double)amount type:(EVPaymentType)type;
@end

@implementation EVPaymentManager {
    id<EVPaymentStrategy> _strategy;
}

- (void)payWithAmount:(double)amount type:(EVPaymentType)type {
    switch (type) {
        case EVPaymentTypeWeChat: _strategy = [EVWeChatPayStrategy new]; break;
        case EVPaymentTypeAlipay: _strategy = [EVAlipayPayStrategy new]; break;
        case EVPaymentTypeApplePay: _strategy = [EVApplePayStrategy new]; break;
    }
    [_strategy payWithAmount:amount];
}
@end

系统 API / 三方库示例

  • UICollectionViewLayout 使用策略模式封装布局算法(FlowLayout / CustomLayout)
  • 广告 SDK 中不同广告展示策略可用策略模式切换

分析

  • 业务方只调用 Manager,策略对象对业务方透明
  • 适合同一类型对象有多种行为选择的场景
  • 内部策略对象可使用组合模式实现

三、工厂模式(Factory)

场景背景

ResponseSerializer 可以处理 JSON / XML,业务方不想关心初始化逻辑。

设计原理

工厂模式封装对象创建,业务方只关心“拿到对象”,不关心对象是怎么创建的。

代码示例

@protocol EVResponseSerializer <NSObject>
- (id)serializeResponse:(NSData *)data error:(NSError **)error;
@end

@interface EVJSONResponseSerializer : NSObject <EVResponseSerializer> @end
@interface EVXMLResponseSerializer : NSObject <EVResponseSerializer> @end

@interface EVResponseSerializerFactory : NSObject
+ (id<EVResponseSerializer>)serializerWithType:(EVResponseSerializerType)type;
@end

@implementation EVResponseSerializerFactory
+ (id<EVResponseSerializer>)serializerWithType:(EVResponseSerializerType)type {
    switch (type) {
        case EVResponseSerializerTypeJSON: return [EVJSONResponseSerializer new];
        case EVResponseSerializerTypeXML:  return [EVXMLResponseSerializer new];
    }
}
@end

系统 API / 三方库示例

  • UIButton +buttonWithType: 工厂方法生成不同类型按钮
  • AFNetworking 内部根据 responseSerializer 类型生成对应对象

分析

  • 对象创建和初始化细节全部封装
  • 工厂模式解决“对象创建逻辑复杂或多样化”的问题
  • 内部对象也可组合策略对象

四、模式对比

模式 核心关注 使用者感知 实际应用
组合模式 对象组合和复用 调用统一接口,底层组合对象 UIViewController 内部对象组合,MMKV缓存
策略模式 行为可替换 调用统一接口,不关心策略对象 支付方式、广告策略、UICollectionViewLayout
工厂模式 对象创建封装 得到对象,不关心创建细节 UIButton 工厂方法,ResponseSerializer

总结:

  • 组合模式是基础,封装对象,提高复用性
  • 策略模式封装行为,可动态切换
  • 工厂模式封装对象创建,屏蔽初始化细节

五、实践建议

  • 三种模式常常 同时使用
  • 组合模式管理内部对象
  • 策略模式管理可切换行为
  • 工厂模式管理对象创建

掌握这些模式,你就可以写出灵活、可扩展、可维护的 iOS 架构。

Demo地址 https://github.com/EvanCaiDev/iOSArchSeriesDemo

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容