意圖:
提供一個接口捆愁,用來創(chuàng)建一組相關或者相互依賴的對象割去,而無需指定他們的具體類
適用范圍:
提供一個產品類庫,顯示它們的接口昼丑,隱藏具體實現呻逆,使系統(tǒng)獨立于產品的創(chuàng)建、組合菩帝、表示
缺點:
當有新增品類的時候咖城,同時需要拓展抽象工廠和具體工廠
解決方案:
抽象工廠需要更抽象,不再關心產品的品類呼奢,具體工廠需要更具體宜雀,只提供一種產品的規(guī)格參數
具體實現:
通過反射機制運行時動態(tài)創(chuàng)建產品,具體工廠不再負責生產握础,而是提供產品的具體參數辐董,抽象工廠通過產品參數反射出具體工廠,然后生產一個產品
實踐-app殼工程
大型app基本都經歷過從簡單架構到復雜架構的演進禀综,像支付寶简烘、美團這種體量的app不拆分業(yè)務線簡直就是災難,本文以一個app為工廠定枷,該工廠生產各種業(yè)務線孤澎,就拿美團來舉例,有騎行依鸥、打車亥至、電影悼沈、外賣業(yè)務線
定義一個業(yè)務線工廠協(xié)議AbstractFactoryProtocol.h贱迟,該協(xié)議只描述各個業(yè)務線的通用行為姐扮,比如是否是單例
@protocol AbstractFactoryProtocol <NSObject>
@optional
+ (id)shareInstance;
@end
定義一個抽象工廠類AbstractFactory,用單例來描述衣吠,該類負責通過產品規(guī)格參數茶敏,反射出具體工廠,然后生產產品
@interface AbstractFactory : NSObject
+ (instancetype)sharedFactory;
- (id)createProduct:(Protocol *)protocol;
@end
AbstractFactory的實現內容如下
static NSString *kProtocol = @"FactoryMethodProtocol";
static NSString *kViewController = @"Page";
@implementation AbstractFactory
+ (instancetype)sharedFactory {
static id sharedFactory = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedFactory = [[self alloc] init];
});
return sharedFactory;
}
- (id)createProduct:(Protocol *)protocol {
NSString *protocolName = NSStringFromProtocol(protocol);
NSString *className = [protocolName stringByReplacingOccurrencesOfString:kProtocol withString:kViewController];
Class implClass = NSClassFromString(className);
if (!implClass) {
@throw [NSException exceptionWithName:NSInternalInconsistencyException reason:[NSString stringWithFormat:@"%@ protocol does not have match class", protocolName] userInfo:nil];
}
if ([[implClass class] respondsToSelector:@selector(shareInstance)]) {
return [[implClass class] shareInstance];
}
return [[implClass alloc] init];
}
@end
定義一個具體工廠集合SpecificProducts.h
#ifndef SpecificProducts_h
#define SpecificProducts_h
#import "BikeFactoryMethodProtocol.h"
#import "CarFactoryMethodProtocol.h"
#import "MovieFactoryMethodProtocol.h"
#import "TakeoutFactoryMethodProtocol.h"
#endif /* SpecificProducts_h */
具體工廠繼承抽象工廠協(xié)議
@protocol BikeFactoryMethodProtocol <NSObject, AbstractFactoryProtocol>
@end
定義具體產品缚俏,騎行惊搏、打車、電影忧换、外賣
@interface BikePage : UIViewController
@end
@interface CarPage : UIViewController
@end
@interface MoviePage : UIViewController
@end
@interface TakeoutPage : UIViewController
@end
客戶端只需要引用抽象工廠和具體工廠集合即可生產所有產品
id<BikeFactoryMethodProtocol> item0 = [[AbstractFactory sharedFactory] createProduct:@protocol(BikeFactoryMethodProtocol)];
id<CarFactoryMethodProtocol> item1 = [[AbstractFactory sharedFactory] createProduct:@protocol(CarFactoryMethodProtocol)];
id<MovieFactoryMethodProtocol> item2 = [[AbstractFactory sharedFactory] createProduct:@protocol(MovieFactoryMethodProtocol)];
id<TakeoutFactoryMethodProtocol> item3 = [[AbstractFactory sharedFactory] createProduct:@protocol(TakeoutFactoryMethodProtocol)];
總結
更具體的做法是恬惯,各個業(yè)務線會拆包開發(fā),各自維護自己的業(yè)務線協(xié)議亚茬,新增業(yè)務線只需要在殼工程配置自己的協(xié)議即可酪耳,本文demo地址,該方案彌補了抽象工廠模式的拓展問題刹缝,但是存在字符串硬編碼問題碗暗,若有類和協(xié)議不匹配會拋出異常,這里推薦阿里出品的iOS解耦神器BeeHive梢夯,它的做法是言疗,用一個全局的字典保存協(xié)議與類名字的映射關系,當然這也是一種硬編碼颂砸,只不過用起來更靈活噪奄,協(xié)議和類可以隨意命名