iOS適配器設計模式

(-) 提出問題

朋友們在開發(fā)中有沒有遇到過這種情況:開發(fā)中寫了一個視圖控件兜材,雖然這個控件只是一個展示類的,并沒有什么交互。但是在項目好幾個地方都用到了這個控件了,你在給這個視圖控件負值的時候是怎么做的呢最楷?
是不是這么寫的呢?

-(void)laodData:(ItemModel*)model ;

這么寫沒有錯待错,而且感覺很簡單籽孙。但是有兩點不好:

  1. 視圖根數(shù)據(jù)模型有耦合,視圖類引入了模型火俄。

2.當你在項目里其他的地方用到了這個視圖類犯建,而且對應的模型不再是ItemModel了,而是一個新的模型瓜客,比如說ContentModel胎挎,這個時候你要再寫一個初始化方法嗎?類似:

-(void)laodData:(ContentModel*)model ;

這樣寫似乎也沒有錯忆家,但是如多更多地方用了怎么辦?
你有沒有想過德迹,我不同的地方用到一個控件芽卿,為什么要改寫好的視圖控件呢?有沒有別的方法能讓我寫的視圖控件獨立出來胳搞,不和數(shù)據(jù)模型產(chǎn)生耦合呢卸例?這就用到了設計模式中的一個適配器模式了称杨。

(二 )適配器設計模式 簡介

將一個類的接口轉(zhuǎn)換成客戶希望的另外一個接口。Adapter 模式使得原本由于接口不兼容而不能一起工作的那些類可以一起工作筷转。
適用場景:
1姑原、已經(jīng)存在的類的接口不符合我們的需求;
2呜舒、創(chuàng)建一個可以復用的類锭汛,使得該類可以與其他不相關(guān)的類或不可預見的類(即那些接口可能不一定兼容的類)協(xié)同工作;
3袭蝗、在不對每一個都進行子類化以匹配它們的接口的情況下唤殴,使用一些已經(jīng)存在的子類。

(三 )使用適配器模式重構(gòu)代碼

下面從一個例子中看下適配器的寫法:

項目中有一個視圖類到腥,展示一個效果朵逝,前面是一個圖片,圖片的后面是一段文字乡范,這個控件在項目里多處使用配名,并且對應不同的數(shù)據(jù)模型:效果如下


屏幕快照 2016-09-24 下午4.02.01.png
第1步 修改視圖接收數(shù)據(jù)方法

把視圖控件的初始化數(shù)據(jù)改為接收一個遵守某個協(xié)議的數(shù)據(jù)

-(void)loadData:(id  <ContentViewAdapterProtocol>)data{
    self.image      = [data image];
    self.contentStr = [data contentStr];
}

不管傳過來的數(shù)據(jù)是什么類型,只要服從這個協(xié)議晋辆,實現(xiàn)協(xié)議里的方法渠脉,視圖就能處理這個數(shù)據(jù)了

第2步 實現(xiàn)這個協(xié)議

新建也個協(xié)議文件

@protocol ContentViewAdapterProtocol <NSObject>

-(UIImage*)image;

-(NSString*)contentStr;

@end
第3步 創(chuàng)建根適配器類

類遵守上面的協(xié)議,并實現(xiàn)協(xié)議的方法栈拖,但是只是空實現(xiàn)

-(UIImage*)image{
    
    return nil;
}

-(NSString*)contentStr{
    
     return nil;
}

添加初始化數(shù)據(jù)方法

- (instancetype)initWithData:(id)data;

這樣這個適配器就完成了连舍。

第4步 針對不同的類創(chuàng)建適配器

使用適配器的時候分為類適配器和對象適配器,類適配器是針對每一個數(shù)據(jù)類創(chuàng)建一個適配器涩哟。創(chuàng)建的這個適配器類繼承于上面的那個根適配器類索赏。如果要適配另一個數(shù)據(jù)類就需要再新建一個新的適配器類來適配。
新建真對ItemModel的適配器:

#import "ItemModelAdeapter.h"
#import "ItemModel.h"
@implementation ItemModelAdeapter
- (instancetype)initWithData:(id)data{
    self = [super init];
    if (self) {
        
        self.data = data;
        
    }
    
    return self;
}
-(UIImage*)image{

    ItemModel *model =  self.data;

    return model.image;
}

-(NSString*)contentStr{
    ItemModel *model =  self.data;
    
    return model.conntentStr;

}

對象適配器是只創(chuàng)建一個適配器類贴彼,繼承于上面的根適配器潜腻。然后根據(jù)不同的數(shù)據(jù)類返回不同的數(shù)據(jù):

#import "ModelAdapter.h"
#import "ItemModel.h"
#import "ContenModel.h"
//對象適配器
@implementation ModelAdapter
- (instancetype)initWithData:(id)data{
    self = [super init];
    if (self) {
        
        self.data = data;
        
    }
    
    return self;
}
-(UIImage*)image{
    
    if ([self.data isMemberOfClass:[ContenModel class]]) {

    ContenModel *model =  self.data;
        
    return [UIImage imageNamed:model.imageName];
    
    }else{
        
        ItemModel *model =  self.data;
        
        return model.image;

    }
}

-(NSString*)contentStr{
   
    if ([self.data isMemberOfClass:[ContenModel class]]) {
        
        ContenModel *model =  self.data;
        
        return model.conntentStr;
        
    }else{
        
        ItemModel *model =  self.data;
        
        return model.conntentStr;
        
    }
}

對象適配器的好處是在一個類里處理不同的數(shù)據(jù),類會少一些器仗。但是如果要適配的類太多就會顯得很復雜融涣,而對象適配器適配方法分散,類比較多精钮。

第5步 使用適配器

類適配器 適配兩個類

  第一個
    ContenModel *contenModel = [[ContenModel alloc]init];
    contenModel.conntentStr  =  @"時間:10:32:12";
    contenModel.imageName    =  @"shijian";

    ContentViewAdapter *modelAdapter = [[ContentModelAdeapter alloc]initWithData:contenModel];
    
    ContentView *contentView = [[ContentView alloc]initWithFrame:CGRectMake(100, 100, 200, 20)];
    [contentView loadData:modelAdapter];
    [self.view addSubview:contentView];
第二個
 ItemModel *itemModel  = [[ItemModel alloc]init];
    itemModel.conntentStr =  @"心率:100次";
    itemModel.image       =  [UIImage imageNamed:@"mapHeaderIcon"];
    
    ContentViewAdapter *modelAdapter1 = [[ItemModelAdeapter alloc]initWithData:itemModel];
    
    ContentView *contentView1 = [[ContentView alloc]initWithFrame:CGRectMake(100, 200, 200, 20)];
    [contentView1 loadData:modelAdapter1];
    [self.view addSubview:contentView1];

對象適配器

第一個
ItemModel *itemModel1  = [[ItemModel alloc]init];
   itemModel1.conntentStr =  @"心率:100次";
   itemModel1.image       =  [UIImage imageNamed:@"mapHeaderIcon"];
   
   ContentViewAdapter *modelAdapter2 = [[ModelAdapter alloc]initWithData:itemModel];
   
   ContentView *contentView2 = [[ContentView alloc]initWithFrame:CGRectMake(100, 300, 200, 20)];
   [contentView2 loadData:modelAdapter2];
   [self.view addSubview:contentView2];
第二個
ContenModel *contenModel2 = [[ContenModel alloc]init];
   contenModel2.conntentStr  =  @"時間:10:32:12";
   contenModel2.imageName    =  @"shijian";
   
   ContentViewAdapter *modelAdapter3 = [[ModelAdapter alloc]initWithData:contenModel];
   
   ContentView *contentView3 = [[ContentView alloc]initWithFrame:CGRectMake(100, 400, 200, 20)];
   [contentView3 loadData:modelAdapter3];
   [self.view addSubview:contentView3];

(四)適配器模式的缺點

優(yōu)點:

解耦合威鹿,讓視圖類不合數(shù)據(jù)類產(chǎn)生耦合,使視圖類更加獨立轨香。 新增加數(shù)據(jù)類的時候不需要修改視圖類忽你。

缺點:

會新增加很多類,使系統(tǒng)更凌亂臂容,代碼可讀性更弱了科雳。
  
所以大家酌情使用

(五)鳴謝

這篇文章是看過 YouXianMing老師 的教程后根蟹,得到的啟發(fā)并重構(gòu)自己項目代碼后寫的總結(jié)。希望對大家有點幫助糟秘。在此感謝YouXianMing老師简逮。

代碼github下載地址

iOS策略模式

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市尿赚,隨后出現(xiàn)的幾起案子散庶,更是在濱河造成了極大的恐慌,老刑警劉巖吼畏,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件督赤,死亡現(xiàn)場離奇詭異,居然都是意外死亡泻蚊,警方通過查閱死者的電腦和手機躲舌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來性雄,“玉大人没卸,你說我怎么就攤上這事∶胄” “怎么了约计?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長迁筛。 經(jīng)常有香客問我煤蚌,道長,這世上最難降的妖魔是什么细卧? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任尉桩,我火速辦了婚禮,結(jié)果婚禮上贪庙,老公的妹妹穿的比我還像新娘蜘犁。我一直安慰自己,他們只是感情好止邮,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布这橙。 她就那樣靜靜地躺著,像睡著了一般导披。 火紅的嫁衣襯著肌膚如雪屈扎。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天撩匕,我揣著相機與錄音助隧,去河邊找鬼。 笑死,一個胖子當著我的面吹牛并村,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播滓技,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼哩牍,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了令漂?” 一聲冷哼從身側(cè)響起膝昆,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎叠必,沒想到半個月后荚孵,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡纬朝,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年收叶,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片共苛。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡判没,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出隅茎,到底是詐尸還是另有隱情澄峰,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布辟犀,位于F島的核電站俏竞,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏堂竟。R本人自食惡果不足惜魂毁,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望跃捣。 院中可真熱鬧漱牵,春花似錦、人聲如沸疚漆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽娶聘。三九已至闻镶,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間丸升,已是汗流浹背铆农。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留狡耻,地道東北人墩剖。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓猴凹,卻偏偏與公主長得像,于是被迫代替她去往敵國和親岭皂。 傳聞我的和親對象是個殘疾皇子郊霎,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

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

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,506評論 25 707
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件爷绘、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,024評論 4 62
  • 至尊寶曾有言:若上天再予其機會书劝,必當以萬年相伴。只是土至,待其金箍再戴购对,戰(zhàn)甲披身,紫霞已香消玉殞陶因,殊為憾事骡苞。 聊齋中有...
    梵溫2閱讀 1,138評論 0 1
  • 我以前也愛寫詩 除開上課作業(yè) 大把的柔軟時光 用矯情的語調(diào) 填滿荒廢的思念 那時候還以為 世上最大的別離 只是我離...
    CYparish閱讀 162評論 0 0
  • 還是喜歡奶茶,百次傾聽的奶茶坑赡,永遠的奶茶烙如。 人 為什么 憑感動生死相許 擁抱前 離別后 是否魂夢...
    padma娃娃閱讀 425評論 0 0