意图:
定义一个用于创建对象的接口,让子类决定实例化哪一个类,从而将一个类的实例化延迟到其子类
适用范围:
对象创建接口统一化,实例化职责子类化、局部化
缺点:
通常客户端只关心需要实现的功能,但是此模式仍然需要客户端指定实例化的类
解决方案:
封装一个工厂方法的适配器,该类负责建立产品之间的关联,从而使得客户端只需要使用其功能即可,而不用在指定具体类
具体实现:
通过适配器定义位移枚举,指定产品的类型以及产品之间的聚合关系,具体产品存储在适配器中以备后续使用,这样的好处是,当更换一种产品品类的时候,无需修改客户端的调用
实践-运营活动优先级管理
某些重要功能成型之后,需要一些列的运营活动来拉新和促活,运营活动需要一个统一的后台来配置(最好如此,不然极难协调),端上则需要开发一套运营系统
定义工厂方法抽象类
@interface ActivityFactory : NSObject
- (void)show;
- (void)dismiss;
@end
定义具体产品类继承与工厂
@interface TopActivity : ActivityFactory
@end
@interface BottomActivity : ActivityFactory
@end
@interface FloatingActivity : ActivityFactory
@end
@interface MiddleActivity : ActivityFactory
@end
每个产品实现抽象方法
- (void)show {
NSLog(@"%@ show", NSStringFromClass(self.class));
}
- (void)dismiss {
NSLog(@"%@ dismiss", NSStringFromClass(self.class));
}
定义一个适配器ActivityManager用来管理产品
// 运营位
typedef NS_OPTIONS(NSUInteger, ActivityType) {
ActivityTypeNone = 0, // 无运营位
ActivityTypeFloating = 1 << 1, // 浮窗运营位
ActivityTypeTop = 1 << 2, // 顶部运营位
ActivityTypeBottom = 1 << 3, // 底部运营位
ActivityTypeMiddle = 1 << 4, // 中部运营位
};
NS_ASSUME_NONNULL_BEGIN
@interface ActivityManager : NSObject
+ (instancetype)showWithActivity:(ActivityType)type;
- (void)dismissWithActivity:(ActivityType)type;
@end
NS_ASSUME_NONNULL_END
实现如下
@interface ActivityManager ()
@property (nonatomic, strong) NSMutableDictionary *activityDic;
@end
@implementation ActivityManager
+ (instancetype)showWithActivity:(ActivityType)type {
ActivityManager *manager = ActivityManager.new;
if (type == ActivityTypeNone) {
return manager;
}
if (type & ActivityTypeFloating) {
ActivityFactory *factory = [[FloatingActivity alloc] init];
[factory show];
[manager.activityDic setObject:factory forKey:NSStringFromClass(FloatingActivity.class)];
}
if (type & ActivityTypeTop) {
ActivityFactory *factory = [[TopActivity alloc] init];
[factory show];
[manager.activityDic setObject:factory forKey:NSStringFromClass(TopActivity.class)];
}
if (type & ActivityTypeBottom) {
ActivityFactory *factory = [[BottomActivity alloc] init];
[factory show];
[manager.activityDic setObject:factory forKey:NSStringFromClass(BottomActivity.class)];
}
if (type & ActivityTypeMiddle) {
ActivityFactory *factory = [[MiddleActivity alloc] init];
[factory show];
[manager.activityDic setObject:factory forKey:NSStringFromClass(MiddleActivity.class)];
}
return manager;
}
- (void)dismissWithActivity:(ActivityType)type {
if (type == ActivityTypeNone) {
return;
}
ActivityFactory *factory = nil;
if (type & ActivityTypeFloating) {
factory = [self.activityDic objectForKey:NSStringFromClass(FloatingActivity.class)];
if (factory) {
[factory dismiss];
[self.activityDic removeObjectForKey:NSStringFromClass(FloatingActivity.class)];
}
}
if (type & ActivityTypeTop) {
factory = [self.activityDic objectForKey:NSStringFromClass(TopActivity.class)];
if (factory) {
[factory dismiss];
[self.activityDic removeObjectForKey:NSStringFromClass(TopActivity.class)];
}
}
if (type & ActivityTypeBottom) {
factory = [self.activityDic objectForKey:NSStringFromClass(BottomActivity.class)];
if (factory) {
[factory dismiss];
[self.activityDic removeObjectForKey:NSStringFromClass(BottomActivity.class)];
}
}
if (type & ActivityTypeMiddle) {
factory = [self.activityDic objectForKey:NSStringFromClass(MiddleActivity.class)];
if (factory) {
[factory dismiss];
[self.activityDic removeObjectForKey:NSStringFromClass(MiddleActivity.class)];
}
}
}
客户端调用
@interface ViewController ()
@property (nonatomic, strong) ActivityManager *activityManager;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.activityManager = [ActivityManager showWithActivity:ActivityTypeTop | ActivityTypeMiddle];
[self.activityManager dismissWithActivity:ActivityTypeTop];
}
总结
工厂方法模式配合适配器使用,会具备更好的拓展性,工厂方法的核心是,产品能抽象出统一的接口,然而现实场景中一定会有特殊功能的产品,这时候适配器就更有用了,负责兼容产品的特殊属性,本文demo地址