一 基本定義
- 什么是適配器模式
定義:適配器模式將某個(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) - 應(yīng)用場(chǎng)景
第一點(diǎn):接口不兼容
第二點(diǎn):可以重復(fù)使用的類恨旱,用于與一些彼此沒有太大關(guān)聯(lián)的一些類一起工作
第三點(diǎn):統(tǒng)一輸出接口,輸入端類型無法確定 - 角色劃分
角色一:適配器(核心)
角色二:目標(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;
}