在 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内部组合UIView、UINavigationItem等对象,实现界面功能 -
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 架构。