iOS架構(gòu)設(shè)計(jì)模式之適配器模式

一 基本定義

Demo

  1. 什么是適配器模式
    定義:適配器模式將某個(gè)類的接口轉(zhuǎn)換成客戶端期望的另一個(gè)接口表示,主的目的是兼容性,讓原本因接口不匹配不能一起工作的兩個(gè)類可以協(xié)同工作脯爪。其別名為包裝器(Wrapper)。
    第一點(diǎn):將一個(gè)原始接口轉(zhuǎn)成客戶端需要的接口
    ? ?? ?原始接口--相當(dāng)于:Adaptee
    ? ?? ?客戶端需要接口(調(diào)用者)---相當(dāng)于:Target
    第二點(diǎn):原始接口不兼容現(xiàn)在新的接口,將他們兩個(gè)可以一起工作
    一起工作需要Adapter實(shí)現(xiàn)
  2. 應(yīng)用場(chǎng)景
    第一點(diǎn):接口不兼容
    第二點(diǎn):可以重復(fù)使用的類恨旱,用于與一些彼此沒有太大關(guān)聯(lián)的一些類一起工作
    第三點(diǎn):統(tǒng)一輸出接口,輸入端類型無法確定
  3. 角色劃分
    角色一:適配器(核心)
    角色二:目標(biāo)接口
    角色三:被適配者
    比如UITableView:
    ? ?? ?角色一:適配器 ViewController 實(shí)現(xiàn)UITableView的兩個(gè)delegate
    ? ?? ?角色二:目標(biāo)接口 UI界面坝疼,UITableViewCell畫UI
    ? ?? ?角色三:被適配者 model 將數(shù)據(jù)適配到UI上
    MVC模式下搜贤,ViewController作為適配器,會(huì)出現(xiàn)ViewController臃腫钝凶,可以利用適配器解決類的臃腫仪芒。

二 原理案例-基本結(jié)構(gòu)

1. 類適配器

第一種:類適配器
金額轉(zhuǎn)換->1000USA( Adaptee)->適配(Target)->人民幣6500(Adapter)
? ?? ?適配器:Adapter
? ?? ?? ?? ?特點(diǎn)一:實(shí)現(xiàn)協(xié)議(目標(biāo)接口) 特點(diǎn)二:適配器繼承被適配者
? ?? ?目標(biāo)接口:Target (協(xié)議)
? ?? ?被適配者:Adaptee
Target:(協(xié)議)

@protocol Target <NSObject>
- (float)getRMB;
@end

被適配者:Adaptee 美元

@implementation Adaptee
- (float)getUSA{
    return  1000;
}
@end

適配器:Adapter 人名幣 繼承Adaptee并遵守協(xié)議Target

#import "Target.h"
#import "Adaptee.h"

@interface Adapter : Adaptee<Target>
@end
@implementation Adapter
- (float)getRMB{
    return [self getUSA]*6.5;
}
@end
2. 對(duì)象適配器

金額轉(zhuǎn)換->1000USA->適配->人民幣6500
適配器:ObjectAdapter
? ?? ?? ?? ?特點(diǎn)一:實(shí)現(xiàn)協(xié)議(目標(biāo)接口) 特點(diǎn)二:持有被適配者的引用

// 對(duì)象適配器
//特點(diǎn)一:實(shí)現(xiàn)協(xié)議
//特點(diǎn)二:持有被適配者的引用
#import <Foundation/Foundation.h>
#import "Target.h"
@interface ObjectAdapter : NSObject<Target>
- (float)getRMB;
@end

@interface ObjectAdapter()
@property (nonatomic,strong)Adaptee *adaptee;
@end
@implementation ObjectAdapter
- (instancetype)init:(Adaptee*)adaptee
{
    self = [super init];
    if (self) {
        self.adaptee = adaptee;
    }
    return self;
}
- (float)getRMB{
    return [self.adaptee getUSA]*6.5;
}
@end

三 開發(fā)案例 UITableView (RxDataSource就是例子)

原始代碼:ViewController 臃腫重復(fù)代碼
? ?? ?? 角色一:適配器->ViewController(實(shí)現(xiàn)協(xié)議->兩個(gè)delegate)
? ?? ?? 角色二:目標(biāo)接口->UI界面(抽象)->UITableView(Cell)
? ?? ?? 角色三:被適配者->數(shù)據(jù)(UserModel…)
優(yōu)化代碼,抽象以便復(fù)用:
? ?? ?? 角色一:適配器->BaseAdapter 代替ViewController功能(實(shí)現(xiàn)UITableView的協(xié)議和持有被適配者即數(shù)據(jù))

// 適配器 替換ViewController去實(shí)現(xiàn)UITableView的協(xié)議
//持有被適配者 即數(shù)據(jù)
@interface BaseAdapter : NSObject<UITableViewDelegate, UITableViewDataSource>
@property(nonatomic, strong) NSMutableArray* dataArray;//裝數(shù)據(jù)
@end

@implementation BaseAdapter

- (instancetype)init
{
    self = [super init];
    if (self) {
        self.dataArray = [NSMutableArray array];
    }
    return self;
}

//提供默認(rèn)實(shí)現(xiàn)
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    return 1;
}

//提供默認(rèn)實(shí)現(xiàn)
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)sectio{
    return _dataArray.count;
}

//提供默認(rèn)實(shí)現(xiàn)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    static NSString * showUserInfoCellIdentifier = @"userInfoCell";
    UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:showUserInfoCellIdentifier];
    if (cell == nil){
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
                                      reuseIdentifier:showUserInfoCellIdentifier];
    }
    cell.textLabel.text = @"姓名";
    cell.detailTextLabel.text = @"Dream";
    return cell;
}

適配具體數(shù)據(jù)模型時(shí)可定制UserAdapter

@interface UserAdapter : BaseAdapter

@end
- (instancetype)init{
    self = [super init];
    if (self) {
        //從網(wǎng)絡(luò)獲取數(shù)據(jù)
        [self.dataArray addObject:[[UserModel alloc] init:@"算悟空" tel:@"17785635421"]];
        [self.dataArray addObject:[[UserModel alloc] init:@"豬八戒" tel:@"17785635431"]];
        [self.dataArray addObject:[[UserModel alloc] init:@"唐僧" tel:@"17785635421"]];
        [self.dataArray addObject:[[UserModel alloc] init:@"傻叉" tel:@"17785635421"]];
        [self.dataArray addObject:[[UserModel alloc] init:@"算悟空" tel:@"17785635421"]];
        [self.dataArray addObject:[[UserModel alloc] init:@"豬八戒" tel:@"17785635431"]];
        [self.dataArray addObject:[[UserModel alloc] init:@"唐僧" tel:@"17785635421"]];
        [self.dataArray addObject:[[UserModel alloc] init:@"傻叉" tel:@"17785635421"]];
       
    }
    return self;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    UITableViewCell* cell = [super tableView:tableView cellForRowAtIndexPath:indexPath];
    UserModel* user = [self.dataArray objectAtIndex:indexPath.row];
    cell.textLabel.text = user.name;
    cell.detailTextLabel.text = user.tel;
    return cell;
}

? ?? ??角色二:目標(biāo)接口-> UITableView的協(xié)議
? ?? ??角色三:被適配者->數(shù)據(jù)

- (instancetype)init:(NSString *)name tel:(NSString*)tel
{
    self = [super init];
    if (self) {
        self.name = name;
        self.tel = tel;
    }
    return self;
}

優(yōu)化后的ViewController

@property (nonatomic,strong)UITableView *tableView;
@property (nonatomic,strong)UserAdapter  *adapter;
@end

@implementation ViewController //適配器

- (void)viewDidLoad {
    [super viewDidLoad];
    _adapter = [[UserAdapter alloc]init];
    _tableView = [[UITableView alloc]initWithFrame:self.view.bounds style:UITableViewStyleGrouped];
    [ self.view addSubview:_tableView];
    _tableView.delegate = _adapter;
    _tableView.dataSource = _adapter;
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末耕陷,一起剝皮案震驚了整個(gè)濱河市掂名,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌哟沫,老刑警劉巖饺蔑,帶你破解...
    沈念sama閱讀 219,270評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異嗜诀,居然都是意外死亡猾警,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門隆敢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來发皿,“玉大人,你說我怎么就攤上這事拂蝎⊙ㄊ” “怎么了?”我有些...
    開封第一講書人閱讀 165,630評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)封救。 經(jīng)常有香客問我拇涤,道長(zhǎng),這世上最難降的妖魔是什么誉结? 我笑而不...
    開封第一講書人閱讀 58,906評(píng)論 1 295
  • 正文 為了忘掉前任鹅士,我火速辦了婚禮,結(jié)果婚禮上惩坑,老公的妹妹穿的比我還像新娘掉盅。我一直安慰自己,他們只是感情好以舒,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評(píng)論 6 392
  • 文/花漫 我一把揭開白布趾痘。 她就那樣靜靜地躺著,像睡著了一般蔓钟。 火紅的嫁衣襯著肌膚如雪永票。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,718評(píng)論 1 305
  • 那天滥沫,我揣著相機(jī)與錄音侣集,去河邊找鬼。 笑死兰绣,一個(gè)胖子當(dāng)著我的面吹牛世分,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播缀辩,決...
    沈念sama閱讀 40,442評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼臭埋,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了臀玄?” 一聲冷哼從身側(cè)響起瓢阴,我...
    開封第一講書人閱讀 39,345評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎镐牺,沒想到半個(gè)月后炫掐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體魁莉,經(jīng)...
    沈念sama閱讀 45,802評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡睬涧,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了旗唁。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片畦浓。...
    茶點(diǎn)故事閱讀 40,117評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖检疫,靈堂內(nèi)的尸體忽然破棺而出讶请,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,810評(píng)論 5 346
  • 正文 年R本政府宣布夺溢,位于F島的核電站论巍,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏风响。R本人自食惡果不足惜嘉汰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望状勤。 院中可真熱鬧鞋怀,春花似錦、人聲如沸持搜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽葫盼。三九已至残腌,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間贫导,已是汗流浹背废累。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留脱盲,地道東北人邑滨。 一個(gè)月前我還...
    沈念sama閱讀 48,377評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像钱反,于是被迫代替她去往敵國(guó)和親掖看。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評(píng)論 2 355

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