在學(xué)習(xí)橋接模式之前我們先看下面一個場景
看見上面的圖大家馬上想到的就是使用繼承實現(xiàn)上面的場景,使用繼承肯定沒有錯,但是大家仔細(xì)想一想,加入要新增一個品牌或者一種電腦類型,是不是每一個電腦類型或者每一品牌是不是都需要改動渗磅,那系統(tǒng)的擴(kuò)展性就出現(xiàn)了問題嚷硫,也違背了面向?qū)ο箝_閉原則的設(shè)計,那有沒有更好的設(shè)計方式來實現(xiàn)呢始鱼,就是我們下面要學(xué)習(xí)的橋接模式仔掸。首先我們先看一下橋接模式的UML圖:
通過上面我們可以看到橋接模式將左邊的抽象部分Abstraction與右邊的實現(xiàn)部分Implementor分離,使它們都可以獨立的變化医清,各自維護(hù)起暮,使的系統(tǒng)符合單一原則。橋接模式讓抽象部分和實現(xiàn)部分關(guān)聯(lián)起來会烙,這個關(guān)聯(lián)類似一個橋梁负懦,故稱為橋接模式筒捺。
Abstraction(抽象類):用于定義抽象類的接口,和Implementor和聚合關(guān)系纸厉,其中需要定義一個Implementor類型的對象
RefineAbstractionA(擴(kuò)充抽象類):繼承Abstraction系吭,擴(kuò)充Abstraction定義的接口,是一個具體的類颗品,實現(xiàn)Abstraction里面的接口肯尺,也可以調(diào)用Implementor中定義的業(yè)務(wù)方法
Implementor(實現(xiàn)類接口):定義實現(xiàn)類的接口,該接口不需要與Abstraction接口沒有必然聯(lián)系躯枢,不必與Abstraction接口保持一致则吟。Implementor定義了基本操作,Abstraction定義復(fù)雜操作锄蹂,通過關(guān)聯(lián)關(guān)系氓仲,Abstraction同時具有復(fù)雜操作和基本操作。
ConcreteImplementor(具體實現(xiàn)類):繼承Implementor败匹,實現(xiàn)Implementor里面定義的方法
橋接模式處理多層繼承結(jié)構(gòu)寨昙,處理多維度變化的場景,將各個維度設(shè)計成獨立的繼承結(jié)構(gòu)掀亩,使各個維度可以獨立的擴(kuò)展舔哪,比如上面的電腦結(jié)構(gòu)圖,一個維度是品牌:聯(lián)想槽棍、神州捉蚤、戴爾;一個維度是臺式電腦炼七、筆記本缆巧、平板;UML如下:
代碼如下:
Brand的抽象類使用協(xié)議實現(xiàn):
@protocol?BrandProtocol
- (NSString*)brandName;
- (void)saleBrand;
@end
聯(lián)想品牌類:
#import "Lenovo.h"
@implementation Lenovo
- (void)saleBrand
{
}
- (NSString*)brandName
{
? ? return @"聯(lián)想";
}
@end
ShenZhou品牌和Dell品牌類類似豌拙,只是品牌名字不一樣
臺式電腦類:
@interfaceDeskComputer :NSObject
@property (nonatomic, weak) id<BrandProtocol> brand;
@end
#import "DeskComputer.h"
@implementation DeskComputer
- (instancetype)initWithBrand:(id)brand
{
? ? self= [superinit];
? ? if(self) {
? ? ? ? _brand= brand;
? ? }
? ? return self;
}
- (NSString*)computerName
{
? ? return [NSString stringWithFormat:@"%@%@",self.brand.brandName,[self computerType]];
}
- (NSString*)computerType
{
? ? return @"臺式電腦";
}
- (double)computerPrice
{
? ? return 0.0;
}
@end
筆記本和平板類同上陕悬,只是名字不同
調(diào)用:
? ? Lenovo*lenovoBrand = [[Lenovoalloc]init];
? ? LaptopComputer *computer = [[LaptopComputer alloc] init];
? ? computer.brand= lenovoBrand;
? ? computerNameLabel.text= [computercomputerName];
代碼請見:https://github.com/steven2008/DesignPattens.git
如果使用裝飾設(shè)計模式的話,裝飾者模式介紹見:學(xué)習(xí)iOS設(shè)計二:裝飾模式按傅,代碼我就不寫了捉超,感興趣的可以自己寫或者和我交流,UML圖如下: