iOS 設(shè)計(jì)模式之三(抽象工廠模式)

一、概念

1、工廠方法模式缺陷

? 工廠方法模式通過引入工廠等級(jí)結(jié)構(gòu),解決了簡(jiǎn)單工廠模式中工廠類職責(zé)太重的問題,但由于工廠方法模式中的每個(gè)工廠只生產(chǎn)一類產(chǎn)品,可能會(huì)導(dǎo)致系統(tǒng)中存在大量的工廠類,勢(shì)必會(huì)增加系統(tǒng)的開銷。此時(shí),我們可以考慮將一些相關(guān)的產(chǎn)品組成一個(gè)“產(chǎn)品族”,由同一個(gè)工廠來統(tǒng)一生產(chǎn),這就是抽象工廠模式的基本思想。

2、產(chǎn)品等級(jí)結(jié)構(gòu)和產(chǎn)品族

產(chǎn)品等級(jí)結(jié)構(gòu):

? 即產(chǎn)品的繼承結(jié)構(gòu),比如一個(gè)抽象類是電視機(jī),其子類有海爾電視機(jī)、海信電視機(jī)、TCL電視機(jī),則抽象電視機(jī)與具體品牌的電視機(jī)之間構(gòu)成了一個(gè)產(chǎn)品等級(jí)結(jié)構(gòu),抽象電視機(jī)是父類,而具體品牌的電視機(jī)是其子類。

產(chǎn)品簇:

? 在抽象工廠模式中,產(chǎn)品族是指由同一個(gè)工廠生產(chǎn)的,位于不同產(chǎn)品等級(jí)結(jié)構(gòu)中的一組產(chǎn)品,如海爾電器工廠生產(chǎn)的海爾電視機(jī)、海爾電冰箱,海爾電視機(jī)位于電視機(jī)產(chǎn)品等級(jí)結(jié)構(gòu)中,海爾電冰箱位于電冰箱產(chǎn)品等級(jí)結(jié)構(gòu)中,海爾電視機(jī)、海爾電冰箱構(gòu)成了一個(gè)產(chǎn)品族。

3、抽象工廠模式定義

? 抽象工廠模式(Abstract Factory Pattern):提供一個(gè)創(chuàng)建一系列相關(guān)或相互依賴對(duì)象的接口,而無須指定它們具體的類。抽象工廠模式又稱為 Kit 模式,它是一種對(duì)象創(chuàng)建型模式。

? 抽象工廠模式為創(chuàng)建一組對(duì)象提供了一種解決方案。與工廠方法模式相比,抽象工廠模式中的具體工廠不只是創(chuàng)建一種產(chǎn)品,它負(fù)責(zé)創(chuàng)建一族產(chǎn)品。

4、抽象工廠模式的四個(gè)角色

1)AbstractFactory(抽象工廠):它聲明了一組用于創(chuàng)建一族產(chǎn)品的方法,每一個(gè)方法對(duì)應(yīng)一種產(chǎn)品。

2)ConcreteFactory(具體工廠):它實(shí)現(xiàn)了在抽象工廠中聲明的創(chuàng)建產(chǎn)品的方法,生成一組具體產(chǎn)品,這些產(chǎn)品構(gòu)成了一個(gè)產(chǎn)品族,每一個(gè)產(chǎn)品都位于某個(gè)產(chǎn)品等級(jí)結(jié)構(gòu)中。

3)AbstractProduct(抽象產(chǎn)品):它為每種產(chǎn)品聲明接口,在抽象產(chǎn)品中聲明了產(chǎn)品所具有的業(yè)務(wù)方法。

4)ConcreteProduct(具體產(chǎn)品):它定義具體工廠生產(chǎn)的具體產(chǎn)品對(duì)象,實(shí)現(xiàn)抽象產(chǎn)品接口中聲明的業(yè)務(wù)方法。

? 在抽象工廠中聲明了多個(gè)工廠方法,用于創(chuàng)建不同類型的產(chǎn)品,抽象工廠可以是接口,也可以是抽象類。

5、結(jié)構(gòu)圖
抽象工廠模式

二、示例

? 本Demo還是以工廠生產(chǎn)空調(diào)和洗衣機(jī)為例:

1)先創(chuàng)建兩個(gè)抽象產(chǎn)品AirConditioning空調(diào)和Washer洗衣機(jī)類,表示抽象產(chǎn)品類;

2)然后創(chuàng)建HaierAirConditioning和MideaAirConditioning類,繼承自AirConditioning類,表示具體產(chǎn)品類;

3)然后創(chuàng)建HaierWasher和MideaWasher類,繼承自Washer類,也表示具體產(chǎn)品類;

4)然后創(chuàng)建抽象工廠類AbstractFactory,聲明了一組創(chuàng)建不同產(chǎn)品的方法,表示抽象工廠類;

5)最后創(chuàng)建HaierFactory和MideaFactory類,繼承自AbstractFactory類,表示具體工廠類。

具體代碼如下:

AirConditioning、HaierAirConditioning和MideaAirConditioning類:

// AirConditioning 空調(diào):抽象產(chǎn)品類
@interface AirConditioning : NSObject
- (void)coolAir; //抽象方法
@end
@implementation AirConditioning
- (void)coolAir {}
@end

// HaierAirConditioning 海爾空調(diào):具體產(chǎn)品類
@interface HaierAirConditioning : AirConditioning
@end
@implementation HaierAirConditioning
- (void)coolAir {
    NSLog(@"海爾空調(diào)夏天使用很涼快");
}
@end

// MideaAirConditioning 美的空調(diào):具體產(chǎn)品類
@interface MideaAirConditioning : AirConditioning
@end
@implementation MideaAirConditioning
- (void)coolAir {
    NSLog(@"美的空調(diào)夏天使用也是涼快");
}
@end

Washer、HaierWasher和MideaWasher類:

// Washer 洗衣機(jī):抽象產(chǎn)品類
@interface Washer : NSObject
- (void)washClothes; //抽象方法
@end
@implementation Washer
- (void)washClothes {}
@end

// HaierWasher 海爾洗衣機(jī):具體產(chǎn)品類
@interface HaierWasher : Washer
@end
@implementation HaierWasher
- (void)washClothes {
    NSLog(@"海爾洗衣機(jī)洗衣服很干凈");
}
@end

// MideaWasher 美的洗衣機(jī):具體產(chǎn)品類
@interface MideaWasher : Washer
@end
@implementation MideaWasher
- (void)washClothes {
    NSLog(@"美的洗衣機(jī)洗衣服也是很干凈喲");
}
@end

AbstractFactory、HaierFactory和MideaFactory類:

// AbstractFactory 抽象工廠類
@interface AbstractFactory : NSObject
- (AirConditioning *)createAirConditioning; //工廠方法一
- (Washer *)createWasher; //工廠方法二
@end
@implementation AbstractFactory
- (AirConditioning *)createAirConditioning { return nil; }
- (Washer *)createWasher { return nil; }
@end

// HaierFactory 海爾工廠:具體工廠
@interface HaierFactory : AbstractFactory
@end
@implementation HaierFactory
- (AirConditioning *)createAirConditioning {
    return [HaierAirConditioning new];
}

- (Washer *)createWasher {
    return [HaierWasher new];
}
@end

// MideaFactory 美的工廠:具體工廠
@interface MideaFactory : AbstractFactory
@end
@implementation MideaFactory
- (AirConditioning *)createAirConditioning {
    return [MideaAirConditioning new];
}

- (Washer *)createWasher {
    return [MideaWasher new];
}
@end

運(yùn)行代碼:

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 一個(gè)factory可以創(chuàng)建多個(gè)產(chǎn)品
    AbstractFactory *haier = [HaierFactory new];
    AirConditioning *haierAir = [haier createAirConditioning];
    Washer *haierWasher = [haier createWasher];
    [haierAir coolAir];
    [haierWasher washClothes];
    NSLog(@"-------------------");
    
    AbstractFactory *midea = [MideaFactory new];
    AirConditioning *mideaAir = [midea createAirConditioning];
    Washer *mideaWasher = [midea createWasher];
    [mideaAir coolAir];
    [mideaWasher washClothes];
}

打印結(jié)果:

海爾空調(diào)夏天使用很涼快
海爾洗衣機(jī)洗衣服很干凈
-------------------
美的空調(diào)夏天使用也是涼快
美的洗衣機(jī)洗衣服也是很干凈喲

三、總結(jié)

? 抽象工廠模式是工廠方法模式的進(jìn)一步延伸,因?yàn)樗峁┝斯δ芨鼮閺?qiáng)大的工廠類并且具備較好的可擴(kuò)展性。在抽象工廠模式中,增加新的產(chǎn)品族很方便,但是增加新的產(chǎn)品等級(jí)結(jié)構(gòu)很麻煩,抽象工廠模式的這種性質(zhì)稱為“開閉原則”的傾斜性?!伴_閉原則”要求系統(tǒng)對(duì)擴(kuò)展開放,對(duì)修改封閉。

1、優(yōu)點(diǎn)

1、抽象工廠模式隔離了具體類的生成,使得客戶并不需要知道什么被創(chuàng)建。由于這種隔離,更換一個(gè)具體工廠就變得相對(duì)容易,所有的具體工廠都實(shí)現(xiàn)了抽象工廠中定義的那些公共接口,因此只需改變具體工廠的實(shí)例,就可以在某種程度上改變整個(gè)軟件系統(tǒng)的行為。

2、 當(dāng)一個(gè)產(chǎn)品族中的多個(gè)對(duì)象被設(shè)計(jì)成一起工作時(shí),它能夠保證客戶端始終只使用同一個(gè)產(chǎn)品族中的對(duì)象。

3、增加新的產(chǎn)品族很方便,無須修改已有系統(tǒng),符合“開閉原則”。

2、缺點(diǎn)

? 增加新的產(chǎn)品等級(jí)結(jié)構(gòu)麻煩,需要對(duì)原有系統(tǒng)進(jìn)行較大的修改,甚至需要修改抽象層代碼,這顯然會(huì)帶來較大的不便,違背了“開閉原則”。

3、適用場(chǎng)景

1、一個(gè)系統(tǒng)不應(yīng)當(dāng)依賴于產(chǎn)品類實(shí)例如何被創(chuàng)建、組合和表達(dá)的細(xì)節(jié),這對(duì)于所有類型的工廠模式都是很重要的,用戶無須關(guān)心對(duì)象的創(chuàng)建過程,將對(duì)象的創(chuàng)建和使用解耦。

2、系統(tǒng)中有多于一個(gè)的產(chǎn)品族,而每次只使用其中某一產(chǎn)品族??梢酝ㄟ^配置文件等方式來使得用戶可以動(dòng)態(tài)改變產(chǎn)品族,也可以很方便地增加新的產(chǎn)品族。

3、屬于同一個(gè)產(chǎn)品族的產(chǎn)品將在一起使用,這一約束必須在系統(tǒng)的設(shè)計(jì)中體現(xiàn)出來。同一個(gè)產(chǎn)品族中的產(chǎn)品可以是沒有任何關(guān)系的對(duì)象,但是它們都具有一些共同的約束。

4、產(chǎn)品等級(jí)結(jié)構(gòu)穩(wěn)定,設(shè)計(jì)完成之后,不會(huì)向系統(tǒng)中增加新的產(chǎn)品等級(jí)結(jié)構(gòu)或者刪除已有的產(chǎn)品等級(jí)結(jié)構(gòu)。

4、iOS應(yīng)用舉例

? 比如NSNumber就完全符合抽象工廠模式,你可以通過alloc init創(chuàng)建,還可以通過下方代碼創(chuàng)建:

NSNumber *boolNumber = [NSNumber numberWithBool:YES]; //通過類工廠方法創(chuàng)建各種“數(shù)工廠”
BOOL yes = [boolNumber boolValue];
NSNumber *intNumber = [NSNumber numberWithInt:1];
int num = [intNumber intValue];
NSLog(@"%@", [[boolNumber class] description]); // 結(jié)果:__NSCFBoolean
NSLog(@"%@", [[intNumber class] description]); // 結(jié)果:__NSCFNumber

在這里NSNumber就是抽象工廠,NSCFBoolean和NSCFNumber就是具體工廠,boolValue()和intValue()方法就是工廠方法,返回的yes和num就是具體的產(chǎn)品,返回的產(chǎn)品是不同類型的。

Demo地址:iOS-Design-Patterns

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容