工廠模式三部曲 - 抽象工廠模式

該文章屬于劉小壯原創(chuàng),轉(zhuǎn)載請注明:劉小壯

配圖

這是工廠模式三部曲中的最后一篇了躲撰,在這篇文章中將會講述抽象工廠模式枫耳,抽象工廠模式正如其名字一樣,非常抽象寓落。但是抽象工廠模式的功能卻十分強大炊豪,對抽象工廠的利用也非常好。

這篇文章中會像本系列第一篇一樣鸯檬,給出普通實現(xiàn)方式和使用了反射機制的實現(xiàn)兩種代碼决侈,并且會說明這兩種實現(xiàn)方式的區(qū)別。并且在文章的最后喧务,會將這三種模式放在一起赖歌,對這三種工廠模式進行總結(jié)。

本人理解可能不夠深刻功茴,這一系列文章中存在的問題庐冯,歡迎大家提出,謝謝坎穿!??


什么是抽象工廠模式

簡單了解一下

按照慣例展父,我們先了解一下什么是抽象工廠模式。抽象工廠模式和工廠方法模式很相似赁酝,但是抽象工廠模式將抽象發(fā)揮的更加極致犯祠,是三種工廠模式中最抽象的一種設(shè)計模式。抽象工廠模式酌呆,也叫做Kit模式衡载,提供了創(chuàng)建一系列相關(guān)抽象子類的接口,而無需指定它們具體的類型隙袁。

抽象工廠模式中定義了抽象工廠類痰娱,抽象工廠類中定義了每個系列的抽象子類創(chuàng)建所需的方法,這些方法對應(yīng)著不同類型的抽象子類實例化過程菩收。每個工廠子類都對應(yīng)著一個系列梨睁,工廠子類通過重寫這些方法來實例化當前系列的抽象子類。

工廠方法模式中抽象子類都是基于同一個抽象類的娜饵,是同一個類型的抽象子類坡贺,例如加、減箱舞、乘遍坟、除都屬于運算類型。而抽象工廠模式可能會有多個類型的抽象類晴股,抽象子類分別繼承自對應(yīng)類型的抽象類愿伴,相同類型的抽象子類都是屬于不同系列的

抽象工廠模式包含四部分:
  • 抽象工廠類:定義創(chuàng)建抽象子類的具體行為电湘,根據(jù)系列中不同類型的抽象子類可能會有多種行為隔节。
  • 工廠子類:繼承自抽象工廠類鹅经,根據(jù)當前抽象子類對應(yīng)的系列,重寫父類定義的對應(yīng)行為怎诫。對應(yīng)的抽象子類系列不同瘾晃,行為的實現(xiàn)方式也不同。
  • 抽象類:定義當前類型抽象子類的操作刽虹,子類繼承父類完成具體的操作酗捌。在抽象工廠模式中呢诬,可能會有多種抽象類的定義涌哲。
  • 抽象子類:根據(jù)當前類型繼承自對應(yīng)的抽象類,并根據(jù)系列的不同重寫抽象類定義的實現(xiàn)尚镰。
我打算先講一個例子

我們上面講了系列的概念阀圾,這里將會用一個例子來理解系列和抽象類的關(guān)系。假設(shè)現(xiàn)在需要用SqliteCoreData兩種不同的方式進行本地持久化狗唉,持久化的內(nèi)容都是用戶信息初烘、搜索信息、設(shè)置信息三部分分俯。

就拿Sqlite持久化方式來說肾筐,Sqlite就是使用Sqlite數(shù)據(jù)庫持久化方式的系列,下面對應(yīng)著用戶信息缸剪、搜索信息吗铐、設(shè)置信息三個類型,每個類型就是一個抽象類杏节。除了Sqlite這種持久化方式外唬渗,還有CoreData這種持久化方式,這是兩個不同的持久化方式奋渔,所以屬于兩個不同的系列镊逝。

SqliteCoreData都代表著不同的系列,其下面都分別對應(yīng)著用戶信息嫉鲸、搜索信息撑蒜、設(shè)置信息三個類型的層級,在這種層級關(guān)系中玄渗,Sqlite的用戶信息抽象子類對應(yīng)著CoreData的用戶信息抽象子類座菠,這兩個抽象子類都屬于同一個類型,繼承自同一個抽象類捻爷,分別被不同系列的工廠子類創(chuàng)建辈灼。在抽象設(shè)計模式中,不同系列相同類型的抽象子類都是一一對應(yīng)的也榄。

SqliteCoreData屬于不同的系列巡莹,所以是兩個不同的工廠子類司志,這兩個工廠子類具有相同的行為,就是用戶信息降宅、搜索信息骂远、設(shè)置信息三部分的數(shù)據(jù)持久化,這就是三種不同的持久化類型腰根,也就是我們上面說的類型激才。這三個行為定義在抽象工廠類中,抽象工廠類中定義每個系列的抽象子類創(chuàng)建方法额嘿,SqliteCoreData繼承自抽象工廠類瘸恼,并分別實現(xiàn)繼承過來的抽象子類創(chuàng)建方法。

通過上面的例子册养,我們可以清晰的理解工廠類东帅、抽象類、系列三者之間的關(guān)系球拦,理解這三者的關(guān)系可以有助于我們更好的理解抽象設(shè)計模式靠闭。

和工廠方法模式有什么不同?

在工廠方法模式中坎炼,工廠子類負責(zé)抽象子類的實例化愧膀,每個工廠子類對應(yīng)著一個抽象子類,且具有唯一性谣光。而在抽象工廠模式中檩淋,一個工廠子類代表一個系列,工廠子類根據(jù)當前系列對不同類型的抽象子類進行創(chuàng)建抢肛。工廠方法模式中工廠子類對應(yīng)的是一個類型的抽象子類狼钮,抽象工廠模式對應(yīng)的是一個系列的抽象子類

工廠方法模式一個工廠子類對應(yīng)一個抽象子類的設(shè)計捡絮,會有很大的浪費熬芜,產(chǎn)生了過多的類。而抽象工廠模式更好的利用了工廠子類福稳,使每個工廠子類對應(yīng)著一個系列的抽象子類涎拉,這種設(shè)計非常適用于兩個具有相同結(jié)構(gòu)關(guān)系,但是分屬于不同系列的系列之間的切換的圆。

總之就是鼓拧,工廠方法模式是針對單個類型的抽象類,而抽象工廠模式是針對具有相同結(jié)構(gòu)的一系列類型的抽象類越妈。


業(yè)務(wù)場景

在上面講到了數(shù)據(jù)持久化的例子季俩,我們的業(yè)務(wù)場景也根據(jù)上面的例子提出。

iOS中比較常用的數(shù)據(jù)持久化方案梅掠,應(yīng)該就包括SqliteCoreData了酌住,可能Sqlite的靈活性使其更加受歡迎店归。業(yè)務(wù)就是需要用SqliteCoreData兩種不同的方式進行本地持久化,持久化的內(nèi)容是用戶信息酪我、搜索信息消痛、設(shè)置信息三部分。

通過抽象工廠模式實現(xiàn)上面的需求都哭,可以很方便的進行本地持久化方案的切換秩伞,下面的例子中將會演示一行代碼切換數(shù)據(jù)持久化方案的例子。

UML類圖

我們根據(jù)上面的業(yè)務(wù)場景畫了一個UML類圖欺矫,下面類圖中為了讓大家看得更清晰纱新,所以用不同顏色的線區(qū)分開了對應(yīng)的類和功能

下面的黑色箭頭是抽象子類和抽象類的繼承關(guān)系汇陆;紅色是用戶工廠子類對應(yīng)的抽象子類怒炸;黃色是搜索工廠子類對應(yīng)的抽象子類带饱;綠色是設(shè)置工廠子類對應(yīng)的抽象子類毡代。

抽象工廠模式

在這個UML類圖中,我們可以清晰的看出勺疼,之前工廠方法模式的工廠子類對應(yīng)的是單一類型的抽象子類教寂,上面抽象工廠模式的工廠子類對應(yīng)的是同一系列多個類型的抽象子類,更好的利用了工廠子類执庐,適合更加復(fù)雜的業(yè)務(wù)需求酪耕。抽象工廠類的方法定義也和工廠方法模式不太一樣,由于工廠方法模式只創(chuàng)建一個抽象子類轨淌,所以直接用的類方法定義迂烁,抽象方法模式可能會創(chuàng)建多個類型的抽象子類,所以用的實例方法定義递鹉。

普通方式代碼實現(xiàn)

這里代碼實現(xiàn)按照上面舉的例子盟步,代碼結(jié)構(gòu)也完全按照上面UML類圖中畫的結(jié)構(gòu),使整篇文章可以更加統(tǒng)一躏结,更深刻的理解這個設(shè)計模式却盘。

代碼量比較多,但是為了更好的體現(xiàn)出抽象工廠模式媳拴,所以就全貼出來了黄橘。

首先創(chuàng)建兩個Model類,這兩個Model類并不屬于抽象工廠模式結(jié)構(gòu)的一部分屈溉,只是為了更好的體現(xiàn)出面向模型開發(fā)塞关。
@interface User : NSObject
@property (nonatomic, copy  ) NSString  *userName;
@property (nonatomic, assign) NSInteger userAge;
@end
@implementation User
@end

@interface City : NSObject
@property (nonatomic, copy) NSString *cityName;
@property (nonatomic, copy) NSString *cityCode;
@end
@implementation City
@end
用戶信息系列相關(guān)類
@interface UserInfo : NSObject
- (void)setUserName:(User *)name;
@end
@implementation UserInfo
- (void)setUserName:(User *)name {}
@end

@interface SqliteUserInfo : UserInfo
@end
@implementation SqliteUserInfo
- (void)setUserName:(User *)name {
    NSLog(@"這里編寫數(shù)據(jù)庫持久化方案");
}
@end

@interface CoreDataUserInfo : UserInfo
@end
@implementation CoreDataUserInfo
- (void)setUserName:(User *)name {
    NSLog(@"這里編寫CoreData持久化方案");
}
@end
搜索信息系列相關(guān)類
@interface SearchInfo : NSObject
- (void)setSearchCity:(City *)city;
@end
@implementation SearchInfo
- (void)setSearchCity:(City *)city {}
@end

@interface SqliteSearchInfo : SearchInfo
@end
@implementation SqliteSearchInfo
- (void)setSearchCity:(City *)city {
    NSLog(@"這里編寫數(shù)據(jù)庫持久化方案");
}
@end

@interface CoreDataSearchInfo : SearchInfo
@end
@implementation CoreDataSearchInfo
- (void)setSearchCity:(City *)city {
    NSLog(@"這里編寫CoreData持久化方案");
}
@end
設(shè)置信息系列相關(guān)類
@interface SettingsInfo : NSObject
- (void)resetAllSettings;
@end
@implementation SettingsInfo
- (void)resetAllSettings {}
@end

@interface SqliteSettingsInfo : SettingsInfo
@end
@implementation SqliteSettingsInfo
- (void)resetAllSettings {
    NSLog(@"重置數(shù)據(jù)庫設(shè)置信息");
}
@end

@interface CoreDataSettingsInfo : SettingsInfo
@end
@implementation CoreDataSettingsInfo
- (void)resetAllSettings {
    NSLog(@"重置CoreData設(shè)置信息");
}
@end
工廠抽象相關(guān)類
@interface Factory : NSObject
- (UserInfo *)CreateUserInfo;
- (SearchInfo *)CreateSearchInfo;
- (SettingsInfo *)CreateSettingsInfo;
@end
@implementation Factory
- (UserInfo *)CreateUserInfo {
    return nil;
}
- (SearchInfo *)CreateSearchInfo {
    return nil;
}
- (SettingsInfo *)CreateSettingsInfo {
    return nil;
}
@end

@interface SqliteFactory : Factory
@end
@implementation SqliteFactory
- (UserInfo *)CreateUserInfo {
    return [SqliteUserInfo new];
}
- (SearchInfo *)CreateSearchInfo {
    return [SqliteSearchInfo new];
}
- (SettingsInfo *)CreateSettingsInfo {
    return [SqliteSettingsInfo new];
}
@end

@interface CoreDataFactory : Factory
@end
@implementation CoreDataFactory
- (UserInfo *)CreateUserInfo {
    return [CoreDataUserInfo new];
}
- (SearchInfo *)CreateSearchInfo {
    return [CoreDataSearchInfo new];
}
- (SettingsInfo *)CreateSettingsInfo {
    return [CoreDataSettingsInfo new];
}
@end
外界使用
- (void)viewDidLoad {
    User *user = [User new];
    City *city = [City new];

    Factory *factory = [SqliteFactory new];
    UserInfo *userInfo = [factory CreateUserInfo];
    SearchInfo *searchInfo = [factory CreateSearchInfo];
    SettingsInfo *settingsInfo = [factory CreateSettingsInfo];

    [userInfo setUserName:user];
    [searchInfo setSearchCity:city];
    [settingsInfo resetAllSettings];
}

到此為止我們就編寫完抽象工廠設(shè)計模式的代碼了,上面抽象工廠模式的示例中定義了三個類型的抽象類UserInfo子巾、SearchInfo帆赢、SettingsInfo驶睦,抽象子類分別繼承不同類型的抽象類,并實現(xiàn)不同系列的持久化代碼匿醒。這三個類型的抽象類中定義了兩種不同的數(shù)據(jù)持久化方案场航,分別是Sqlite存儲和CoreData存儲,這就是兩種數(shù)據(jù)持久化系列廉羔,分別用SqliteFactoryCoreDataFactory表示這兩個系列溉痢。

代碼中定義了抽象工廠類Factory類,并定義了三個抽象接口用來實例化不同類型的抽象子類憋他,兩個工廠子類SqliteFactoryCoreDataFactory繼承自抽象工廠類孩饼,內(nèi)部分別實現(xiàn)了兩種不同系列的抽象子類實例化,例如SqliteFactory中會實例化關(guān)于Sqlite存儲方式的抽象子類竹挡,并通過抽象工廠類中定義的抽象接口返回給外界使用镀娶。

統(tǒng)一控制工廠子類的切換

這三種工廠設(shè)計模式中除了簡單工廠模式,工廠方法模式和抽象工廠模式都需要外界實例化不同的工廠子類揪罕,這種在外界實例化工廠子類的代碼可能會出現(xiàn)在多個地方梯码,而在很多業(yè)務(wù)需求中都需要我們統(tǒng)一切換某個功能,從代碼上來說就是切換工廠子類好啰,怎樣可以做到統(tǒng)一切換工廠子類的需求呢轩娶?

就拿上面的持久化方案的例子來說,我們定義了兩種持久化方案框往,通過SqliteFactoryCoreDataFactory工廠子類來創(chuàng)建不同的持久化方案鳄抒。假設(shè)現(xiàn)在我們項目比較龐大,代碼量比較多椰弊,并且在多個地方用到了SqliteFactory工廠子類许溅,現(xiàn)在需求是切換為CoreDataFactory的持久化方案,我們應(yīng)該怎樣快速的切換持久化方案秉版?

其實我們可以通過typedef定義別名的方式切換工廠子類贤重,在其他地方只需要使用我們typedef定義的別名就可以,例如下面代碼就可以做到修改一處typedef定義沐飘,就修改了整個項目的持久化方案游桩。

還是按照上面的抽象工廠模式的代碼,這里只寫出外界使用的代碼部分
typedef SqliteFactory SaveFactory; //定義的工廠子類別名

@implementation TestTableViewController
- (void)viewDidLoad {
    User *user = [User new];
    City *city = [City new];

    Factory *factory = [SaveFactory new];
    UserInfo *userInfo = [factory CreateUserInfo];
    SearchInfo *searchInfo = [factory CreateSearchInfo];
    SettingsInfo *settingsInfo = [factory CreateSettingsInfo];

    [userInfo setUserName:user];
    [searchInfo setSearchCity:city];
    [settingsInfo resetAllSettings];
}

從上面的代碼可以看到耐朴,我們定義了一個SaveFactory的工廠子類別名借卧,下面直接通過這個別名進行的工廠子類的實例化。因為如果存儲相同的內(nèi)容筛峭,項目中只會出現(xiàn)一種持久化方案铐刘,所以我們只需要修改typedef的定義,就可以切換整個項目的持久化方案影晓。

配合反射機制優(yōu)化代碼

對于抽象工廠模式的反射機制镰吵,實現(xiàn)方式和之前的簡單工廠模式不太一樣檩禾,我采用的是預(yù)編譯指令加常量字符串類名反射的方式實現(xiàn)的。別的不多說疤祭,先上代碼來看看盼产,我這里貼出了主要代碼,其他一樣的地方我就不往外貼了勺馆,不浪費大家時間戏售。

還是按照上面的業(yè)務(wù)場景,我定義了兩種同名不同值的字符串常量草穆,這些常量字符串對應(yīng)的就是抽象子類的類名灌灾,一個條件分支就是一個系列的抽象子類,通過預(yù)編譯指令#if來進行不同系列的抽象子類間的統(tǒng)一切換悲柱,定義了SAVE_DATA_MODE_SQLITE宏定義來控制系列的切換锋喜。這種定義方式可以更方便的進行不同系列間的切換,從使用上來看非常像我們用預(yù)編譯指令替換了之前的工廠子類豌鸡,實際上從代碼的角度上來說這種方式對系列間的切換更加統(tǒng)一和方便嘿般。

#define SAVE_DATA_MODE_SQLITE 1

#if SAVE_DATA_MODE_SQLITE
static NSString * const kUserInfoClass     = @"SqliteUserInfo";
static NSString * const kSearchInfoClass   = @"SqliteSearchInfo";
static NSString * const kSettingsInfoClass = @"SqliteSettingsInfo";
#else
static NSString * const kUserInfoClass     = @"CoreDataUserInfo";
static NSString * const kSearchInfoClass   = @"CoreDataSearchInfo";
static NSString * const kSettingsInfoClass = @"CoreDataSettingsInfo";
#endif

下面是工廠類的定義,使用反射機制的抽象工廠模式刨除了工廠子類直颅,只用一個工廠類來進行操作子類的實例化博个,這種方式和之前的簡單工廠模式非常相似。不同的是之前的簡單工廠模式只需要初始化一個類型的抽象子類功偿,而抽象工廠模式需要初始化多個類型的抽象子類

由于我們采用了反射機制往堡,并且由預(yù)編譯指令進行系列間的切換械荷,所以這里就直接使用類方法了,哪里用就直接實例化抽象子類即可虑灰,不存在工廠子類之間的選擇問題了吨瞎。

@interface Factory : NSObject
+ (UserInfo *)CreateUserInfo;
+ (SearchInfo *)CreateSearchInfo;
+ (SettingsInfo *)CreateSettingsInfo;
@end

@implementation Factory
+ (UserInfo *)CreateUserInfo {
    return [[NSClassFromString(kUserInfoClass) alloc] init];
}
+ (SearchInfo *)CreateSearchInfo {
    return [[NSClassFromString(kSearchInfoClass) alloc] init];
}
+ (SettingsInfo *)CreateSettingsInfo {
    return [[NSClassFromString(kSettingsInfoClass) alloc] init];
}
@end

通過這種方式進行不同系列的切換,只需要修改一個宏定義的值即可穆咐,也就是SAVE_DATA_MODE_SQLITE后面的1切換為0的步驟颤诀,這種方式是符合我們開放封閉原則的。以后每個系列增加新的類型后对湃,只需要將新增加的兩個類名對應(yīng)添加在預(yù)編譯指令中崖叫,在工廠方法中擴展一個實例化新類型的方法即可。這種方式對擴展是開放的拍柒,對修改是關(guān)閉的心傀。

對于上面的示例代碼的編寫需要注意一下,按照蘋果的命名規(guī)范拆讯,常量的作用域如果只在一個類中脂男,前面就用小寫k修飾养叛,如果修飾的常量在其他類中用到,也就是.h文件中用extern修飾的常量宰翅,不需要用小寫k修飾弃甥。我們在蘋果的很多官方代碼和Kit中也可以看到相同的定義,宏定義也是相同的規(guī)則汁讼。(extern修飾的常量在.m中不要用static修飾)

項目中如果用到任何預(yù)編譯指令潘飘,在修改重新運行前,一定要clear一下掉缺,清除緩存卜录,否則會因為緩存導(dǎo)致bug

抽象工廠模式的優(yōu)缺點

優(yōu)點

抽象工廠模式正如其名字一樣眶明,理解起來非常抽象艰毒,正是因為這種抽象,使得抽象工廠模式非常強大和靈活搜囱,比其他兩種工廠設(shè)計模式要強大很多丑瞧。抽象工廠模式可以創(chuàng)建多個系列,并且每個系列抽象子類一一對應(yīng)蜀肘,這種強大的功能是其他兩種工廠模式都不能實現(xiàn)的绊汹。

通過抽象工廠模式統(tǒng)一控制多個系列的抽象子類,可以用多個系列的抽象子類完成一些復(fù)雜的需求扮宠。例如我們文中說到的本地持久化方案的切換西乖,最后通過我們的不斷優(yōu)化,做到只需要修改一個預(yù)編譯指令的參數(shù)即可切換整個數(shù)據(jù)持久化方案坛增,這是其他工廠模式所不能完成的获雕。

抽象工廠模式延續(xù)了工廠模式的優(yōu)點,外界接觸不到任何類型的抽象子類收捣,而只需要知道不同類型的抽象類即可届案,抽象子類的創(chuàng)建過程都在工廠子類中。這種設(shè)計方式充分的利用了面向?qū)ο笳Z言中的多態(tài)特性罢艾,使靈活性大大提升楣颠。而且抽象工廠模式是非常符合開放封閉原則的,對擴展的開放以及對修改的封閉都完美支持咐蚯。

缺點

抽象工廠模式帶來的缺點也是顯而易見的童漩,最明顯的缺點就是模式比較龐大,所以需要在適合的業(yè)務(wù)場景使用這種模式仓蛆,否則會適得其反睁冬。


工廠模式三部曲總結(jié)

示例

到目前為止,工廠模式三部曲中的三種工廠模式都已經(jīng)講完了,在這里我們將簡單回顧和總結(jié)一下這三種設(shè)計模式豆拨。首先直奋,我將根據(jù)三種工廠模式畫三張同樣需求的UML類圖,看完這三張類圖大家就對三種工廠模式清晰明了了施禾。

需求就以現(xiàn)在比較火的樂視系列的樂視TV脚线、樂視手機,小米系列的小米TV弥搞、小米手機來作為需求邮绿,這三張圖主要體現(xiàn)工廠模式的整體架構(gòu)。

簡單工廠模式
工廠方法模式
抽象工廠模式

從這三張圖中可以看出攀例,簡單工廠模式和工廠方法模式對應(yīng)的是同一類型的操作結(jié)構(gòu)船逮,在當前例子中就是手機類型,因為只有一個類型粤铭,所以還沒有系列的概念挖胃。在需求不太復(fù)雜,并且不需要多個系列間的切換時梆惯,可以考慮使用這兩種設(shè)計模式酱鸭。

之前的業(yè)務(wù)只有手機一種類型,在業(yè)務(wù)復(fù)雜之后出現(xiàn)了一個新類型的產(chǎn)品-電視垛吗,這時候工廠類就需要增加一種類型凹髓。由于需求更加復(fù)雜,這時候就出現(xiàn)了系列的概念(之前工廠方法模式中類型單一怯屉,所以不需要系列的概念)蔚舀,樂視系列和小米系列,工廠子類變成了每個工廠子類對應(yīng)一個系列的設(shè)計蚀之,每個系列中對應(yīng)不同類型的產(chǎn)品蝗敢。

抽象工廠模式對應(yīng)多個類型的操作結(jié)構(gòu),分屬于不同的系列足删。這種結(jié)構(gòu)比較適合復(fù)雜的業(yè)務(wù)需求,例如文中將的Sqlite數(shù)據(jù)庫和CoreData兩種存儲方式的切換锁右,通過抽象工廠模式就非常好實現(xiàn)失受。

工廠模式總結(jié)

在這三種設(shè)計模式中都有一個共同的特點,就是繼承自抽象類的抽象子類或工廠子類咏瑟,都必須對抽象類定義的方法給出對應(yīng)的實現(xiàn)(可以相同拂到,也可以不同),這種模式才叫做工廠模式码泞。工廠模式的核心就是抽象和多態(tài)兄旬,抽象子類繼承自抽象類,對抽象類中定義的方法和屬性給出不同的實現(xiàn)方式,通過多態(tài)的方式進行方法實現(xiàn)和調(diào)用领铐,構(gòu)成了工廠模式的核心悯森。

在工廠類中對開放封閉原則有著完美的體現(xiàn),對擴展的開放以及對修改的封閉绪撵。例如最抽象的抽象工廠模式瓢姻,抽象工廠模式中增加新的系列,直接擴展一個工廠子類及對應(yīng)的抽象子類音诈,對整個模式框架不會帶來其他影響幻碱。如果增加一個新的類型,創(chuàng)建新的類型對應(yīng)的類细溅,并對整個抽象工廠類及其子類進行方法擴展褥傍。

在外界使用抽象子類的功能時,不需要知道任何關(guān)于抽象子類的特征喇聊,抽象子類也不會出現(xiàn)在外界恍风,外界只需要和抽象類打交道就可以。工廠模式將抽象子類的創(chuàng)建和實現(xiàn)分離承疲,具體的創(chuàng)建操作由工廠類來進行邻耕,抽象子類只需要關(guān)注業(yè)務(wù)即可,外界不需要知道抽象子類實例化的過程燕鸽。這種方式非常靈活并易于擴展兄世,而且在大型項目中尤為明顯,可以很好的避免代碼量過多的問題啊研。

對于這三種工廠模式的選擇御滩,我建議如果是像Sqlite數(shù)據(jù)庫和CoreData切換,這樣業(yè)務(wù)中存在多個系列的需求党远,使用抽象工廠模式削解。如果比較簡單的創(chuàng)建單個類型的抽象子類,這種方式建議用簡單工廠模式或工廠方法模式沟娱。三種設(shè)計模式的選擇還是要看需求和項目復(fù)雜度氛驮,用得好的話可以給代碼帶來極大的靈活性和擴展性

總結(jié)

設(shè)計模式主要是一種思想方面的東西济似,沒有任何一種設(shè)計模式是萬能的矫废,并適應(yīng)于各種業(yè)務(wù)場景的設(shè)計模式。所以在不同的地方使用對應(yīng)的設(shè)計模式砰蠢,或者說根據(jù)業(yè)務(wù)需要設(shè)計一種適合當前業(yè)務(wù)場景的設(shè)計模式蓖扑,這才是最理想的設(shè)計模式用法。


前段時間寫了關(guān)于工廠模式的系列文章台舱,這系列文章理解起來比較難懂律杠。應(yīng)廣大讀者的需要,這段時間專門給這系列文章補了Demo

Demo只是來輔助讀者更好的理解文章中的內(nèi)容柜去,應(yīng)該博客結(jié)合Demo一起學(xué)習(xí)灰嫉,只看Demo還是不能理解更深層的原理Demo中代碼都會有注釋诡蜓,各位可以打斷點跟著Demo執(zhí)行流程走一遍熬甫,看看各個階段變量的值。

Demo地址劉小壯的Github

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蔓罚,一起剝皮案震驚了整個濱河市椿肩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌豺谈,老刑警劉巖郑象,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異茬末,居然都是意外死亡厂榛,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進店門丽惭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來击奶,“玉大人,你說我怎么就攤上這事责掏」窭” “怎么了?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵换衬,是天一觀的道長痰驱。 經(jīng)常有香客問我,道長瞳浦,這世上最難降的妖魔是什么担映? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮叫潦,結(jié)果婚禮上蝇完,老公的妹妹穿的比我還像新娘。我一直安慰自己矗蕊,他們只是感情好四敞,可當我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著拔妥,像睡著了一般。 火紅的嫁衣襯著肌膚如雪达箍。 梳的紋絲不亂的頭發(fā)上没龙,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天,我揣著相機與錄音,去河邊找鬼硬纤。 笑死解滓,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的筝家。 我是一名探鬼主播洼裤,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼溪王!你這毒婦竟也來了腮鞍?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤莹菱,失蹤者是張志新(化名)和其女友劉穎移国,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體道伟,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡迹缀,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了蜜徽。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片祝懂。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖拘鞋,靈堂內(nèi)的尸體忽然破棺而出砚蓬,到底是詐尸還是另有隱情,我是刑警寧澤掐禁,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布怜械,位于F島的核電站,受9級特大地震影響傅事,放射性物質(zhì)發(fā)生泄漏缕允。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一蹭越、第九天 我趴在偏房一處隱蔽的房頂上張望障本。 院中可真熱鬧,春花似錦响鹃、人聲如沸驾霜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽跑筝。三九已至逐纬,卻和暖如春杨名,著一層夾襖步出監(jiān)牢的瞬間陡鹃,已是汗流浹背明未。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工钧唐, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人寞酿。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓家夺,卻偏偏與公主長得像,于是被迫代替她去往敵國和親伐弹。 傳聞我的和親對象是個殘疾皇子拉馋,可洞房花燭夜當晚...
    茶點故事閱讀 42,802評論 2 345

推薦閱讀更多精彩內(nèi)容