設計模式——適配器,橋接稽煤,外觀

前言

本文csdn地址:http://blog.csdn.net/game3108/article/details/51174787
本文主要以代碼形式實現(xiàn)每一種設計模式核芽,算是自己的一種復習和實踐。相應的代碼酵熙,也會放到github上轧简。
本文的類圖均來自于《Objective-C編程之道 iOS設計模式解析》。

本篇主要講:

  • 適配器
  • 橋接
  • 外觀

6.適配器

概念:將一個類的接口轉(zhuǎn)換成客戶希望的另一個接口匾二。適配器模式使得原本由于接口不兼容而不能在一起工作的那些類可以一起工作哮独。

適配器主要有兩種實現(xiàn)方式:

  • 類適配器
    通過繼承來適配兩個接口。
  • 對象適配器
    組合一個適配器對象的引用察藐。

類圖:

Paste_Image.png
Paste_Image.png

何時使用:

  • 已有類的接口與需求不匹配皮璧。
  • 想要一個可復用的類,該類能夠同可能帶有不兼容接口的其他類協(xié)作分飞。
  • 需要適配一個類的幾個不同自雷悴务,可是讓每一個子類去子類化一個類適配器又不現(xiàn)實,那么可以使用對象適配器(也叫委托)來適配其父類的接口譬猫。

類適配器的例子:

EATarget對象

#import <Foundation/Foundation.h>

@protocol EATarget <NSObject>
- (void) request;
@end

EAAdaptee對象:

#import <Foundation/Foundation.h>

@interface EAAdaptee : NSObject
- (void) specificRequest;
@end

#import "EAAdaptee.h"

@implementation EAAdaptee
- (void) specificRequest{
}
@end

EAAdapter對象:

#import "EAAdaptee.h"
#import "EATarget.h"

@interface EAAdapter : EAAdaptee<EATarget>

@end

#import "EAAdapter.h"

@implementation EAAdapter

- (void) request{
    [super specificRequest];
    //to do something
    //xxxxxx
}

@end

對象適配器的例子:

delegate(委托)就是一個典型的對象適配器的用法讯檐。
UITableView,通過delegate回調(diào)didSelectRowAtIndexPath操作其他對象染服。其中UITableView為client别洪,UITableViewDelegate為target

OASelectObject Adaptee:

#import <Foundation/Foundation.h>

@interface OASelectObject : NSObject
- (void) didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
@end

#import "OASelectObject.h"

@implementation OASelectObject
- (void) didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    
}
@end

OAUIViewController adapter對象

#import <UIKit/UIKit.h>

@interface OAUIViewController : UIViewController

@end

#import "OAUIViewController.h"
#import "OASelectObject.h"

@interface OAUIViewController ()<UITableViewDelegate,UITableViewDataSource>{
    OASelectObject *_selectObject;
}

@end

@implementation OAUIViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    
    _selectObject = [[OASelectObject alloc]init];
    
    UITableView *tableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
    tableView.backgroundColor = [UIColor blackColor];
    tableView.delegate = self;
    tableView.dataSource = self;
    [self.view addSubview:tableView];
    // Do any additional setup after loading the view.
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark UITableViewDataSource

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return 1;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    NSString *cellIdentifier = @"cell_identifier";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if ( !cell ){
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
        cell.backgroundColor = [UIColor grayColor];
    }
    
    return cell;
}

#pragma mark UITableViewDelegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    [_selectObject didSelectRowAtIndexPath:indexPath];
}

@end

7.橋接

概念:將抽象部分與它的實現(xiàn)部分分離,使它們都可以獨立地變化柳刮。

類圖:

Paste_Image.png

何時使用:

  • 不想在抽象與其實現(xiàn)之間形成固定的綁定關系(這樣就能在運行時切換實現(xiàn))挖垛。
  • 抽象及其實現(xiàn)都應可以通過子類化獨立進行擴展痒钝。
  • 對抽象的實現(xiàn)進行修改不應影響客戶端代碼。
  • 如果每個實現(xiàn)需要額外的子類以細化抽象痢毒,則說明有必要把它們分為兩個部分送矩。
  • 想在帶有不同抽象接口的多個對象之間共享一個實現(xiàn)。

代碼場景:
電視遙控器會根據(jù)不同電視機改變它的實現(xiàn)哪替,而且遙控器本身也會改變益愈。所以抽象出電視和遙控器兩個抽象類出來。

電視類:

#import <Foundation/Foundation.h>

@interface TV : NSObject
- (void)on;
- (void)off;
- (void)tuneChannel:(NSInteger)channel;
@end

#import "TV.h"

@interface TV(){
    NSInteger _nowChannel;
    BOOL _onShow;
}

@end

@implementation TV

- (void)on{
    _onShow = NO;
}
- (void)off{
    _onShow = YES;
}
- (void)tuneChannel:(NSInteger)channel{
    _nowChannel = channel;
}

@end

電視子類:

#import "TV.h"

@interface RCA : TV

@end

#import "RCA.h"

@implementation RCA
- (void)tuneChannel:(NSInteger)channel{
    NSLog(@"RCA tunechannel");
    [super tuneChannel:channel];
}
@end
#import "TV.h"

@interface Sony : TV

@end

#import "Sony.h"

@implementation Sony
- (void)tuneChannel:(NSInteger)channel{
    NSLog(@"Sony tunechannel");
    [super tuneChannel:channel];
}
@end

遙控類:

#import <Foundation/Foundation.h>
#import "TV.h"

@interface RemoveControl : NSObject
@property (nonatomic, strong) TV *implementor;
- (void) on;
- (void) off;
- (void) setChannel:(NSInteger)channel;
@end

#import "RemoveControl.h"

@implementation RemoveControl
- (void) on{
    [_implementor on];
}
- (void) off{
    [_implementor off];
}
- (void) setChannel:(NSInteger)channel{
    [_implementor tuneChannel:channel];
}
@end

遙控子類:

#import "RemoveControl.h"

@interface ConcreteRemote : RemoveControl
- (void) setStation:(NSInteger)station;
- (void) nextChannel;
- (void) previousChannel;
@end

#import "ConcreteRemote.h"

@interface ConcreteRemote(){
    NSInteger _currentStation;
}

@end

@implementation ConcreteRemote
- (void) setStation:(NSInteger)station{
    _currentStation = station;
    [super setChannel:station];
}
- (void) nextChannel{
    [super setChannel:_currentStation + 1];
}
- (void) previousChannel{
    [super setChannel:_currentStation - 1];
}
@end

8.外觀

概念:為系統(tǒng)中的一組接口提供一個統(tǒng)一的接口夷家。外觀定義一個高層接口,讓子系統(tǒng)更易于使用敏释。

結(jié)構(gòu)圖:

Paste_Image.png

何時使用:

  • 子系統(tǒng)正逐漸變得復雜库快。應用模式的過程中演化出許多類≡客纾可以使用外觀為這些子系統(tǒng)類提供一個較簡單的接口义屏。
  • 可以使用外觀對子系統(tǒng)進行分層。每個子系統(tǒng)級別有一個外觀作為入口點蜂大。讓它們通過其外觀進行通信闽铐,可以簡化他們的依賴關系。

代碼場景:
家庭影院看電影的時候奶浦,可能要先放下屏幕兄墅,關燈,然后播放dvd等澳叉。使用外觀可以用一個家庭影院外觀類進行統(tǒng)一管理隙咸。

家庭外觀類:

#import <Foundation/Foundation.h>
#import "DvdPlayer.h"
#import "CdPlayer.h"
#import "Screen.h"
#import "TheaterLights.h"

@interface HomeTheaterFacade : NSObject
@property (nonatomic, strong) DvdPlayer *dvd;
@property (nonatomic, strong) CdPlayer *cd;
@property (nonatomic, strong) Screen *screen;
@property (nonatomic, strong) TheaterLights *lights;
- (void) watchMovie:(NSString*) movie;
- (void) endMovie;
@end

#import "HomeTheaterFacade.h"

@implementation HomeTheaterFacade

- (void) watchMovie:(NSString*) movie{
    NSLog(@"get ready to watch a movie");
    [_lights off];
    [_screen down];
    [_dvd on];
    [_dvd play:movie];
    
}
- (void) endMovie{
    NSLog(@"shutting movie theater down");
    [_lights on];
    [_screen up];
    [_dvd stop];
    [_dvd eject];
    [_dvd off];
}

@end

總結(jié):

1.適配器,橋接成洗,外觀的使用時機五督?

  • 適配器:用于設計完成之后,主要適用于解決兩個已有接口的匹配瓶殃,而接口本身是一個黑匣子充包,你無法去修改接口的實現(xiàn)。
  • 橋接模式:用于設計的初期遥椿,參與接口的類是穩(wěn)定的基矮,用戶可以修改擴展和修改接口的類,但不能改變接口修壕,通過接口繼承實現(xiàn)或者類繼承實現(xiàn)功能擴展愈捅。
  • 外觀模式:用于設計的初期,為一組子接口提供統(tǒng)一接口慈鸠。相對于適配器的小粒度功能繼承蓝谨,更像一個大粒度的適配器灌具,當封裝系統(tǒng)演化的時候,需要新的外觀對象譬巫,而這個對象起到了適配器的作用咖楣。

參考資料

1.《Objective-C編程之道 iOS設計模式解析》
2.《Head First設計模式》
3.設計模式學習筆記十四:適配器模式、橋接模式與外觀模式

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末芦昔,一起剝皮案震驚了整個濱河市诱贿,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌咕缎,老刑警劉巖珠十,帶你破解...
    沈念sama閱讀 222,252評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異凭豪,居然都是意外死亡焙蹭,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評論 3 399
  • 文/潘曉璐 我一進店門嫂伞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來孔厉,“玉大人,你說我怎么就攤上這事帖努∽颍” “怎么了?”我有些...
    開封第一講書人閱讀 168,814評論 0 361
  • 文/不壞的土叔 我叫張陵拼余,是天一觀的道長污桦。 經(jīng)常有香客問我,道長匙监,這世上最難降的妖魔是什么寡润? 我笑而不...
    開封第一講書人閱讀 59,869評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮舅柜,結(jié)果婚禮上梭纹,老公的妹妹穿的比我還像新娘。我一直安慰自己致份,他們只是感情好变抽,可當我...
    茶點故事閱讀 68,888評論 6 398
  • 文/花漫 我一把揭開白布鹃彻。 她就那樣靜靜地躺著家妆,像睡著了一般鹏秋。 火紅的嫁衣襯著肌膚如雪恃轩。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,475評論 1 312
  • 那天勿她,我揣著相機與錄音术奖,去河邊找鬼腰奋。 笑死蝠引,一個胖子當著我的面吹牛阳谍,可吹牛的內(nèi)容都是我干的蛀柴。 我是一名探鬼主播,決...
    沈念sama閱讀 41,010評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼矫夯,長吁一口氣:“原來是場噩夢啊……” “哼鸽疾!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起训貌,我...
    開封第一講書人閱讀 39,924評論 0 277
  • 序言:老撾萬榮一對情侶失蹤制肮,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后递沪,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體豺鼻,經(jīng)...
    沈念sama閱讀 46,469評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,552評論 3 342
  • 正文 我和宋清朗相戀三年款慨,在試婚紗的時候發(fā)現(xiàn)自己被綠了拘领。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,680評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡樱调,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出届良,到底是詐尸還是另有隱情笆凌,我是刑警寧澤,帶...
    沈念sama閱讀 36,362評論 5 351
  • 正文 年R本政府宣布士葫,位于F島的核電站乞而,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏慢显。R本人自食惡果不足惜爪模,卻給世界環(huán)境...
    茶點故事閱讀 42,037評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望荚藻。 院中可真熱鬧屋灌,春花似錦、人聲如沸应狱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽疾呻。三九已至除嘹,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間岸蜗,已是汗流浹背尉咕。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留璃岳,地道東北人年缎。 一個月前我還...
    沈念sama閱讀 49,099評論 3 378
  • 正文 我出身青樓悔捶,卻偏偏與公主長得像,于是被迫代替她去往敵國和親晦款。 傳聞我的和親對象是個殘疾皇子炎功,可洞房花燭夜當晚...
    茶點故事閱讀 45,691評論 2 361

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