今天學(xué)習(xí)了iOS設(shè)計(jì)模式中的適配器模式,適配器有兩種模式
對象適配器模式
-- 在這種適配器模式中爷光,適配器容納一個(gè)它包裹的類的實(shí)例灶芝。在這種情況下麦箍,適配器調(diào)用被包裹對象的物理實(shí)體瓦哎。
類適配器模式
-- 這種適配器模式下砸喻,適配器繼承自已實(shí)現(xiàn)的類(一般多重繼承)柔逼。
現(xiàn)在以一個(gè)例子來說明這種適配器的使用,首先在你的UI控件頭文件里聲明你需要用來適配的方法
- (void)loadData:(id <BusinessCardAdapterProtocol>)data;
再到你的UI控件.m里面實(shí)現(xiàn)相應(yīng)控件的屬性賦值,然后新建一個(gè)BusinessCardAdapterProtocol
協(xié)議,假如UI控件的需要外界設(shè)置下面這三種屬性
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *phoneNumber;
@property (nonatomic, strong) UIColor *lineColor;
則在BusinessCardAdapterProtocol
協(xié)議里面聲明
- (NSString *)name;
- (UIColor *)lineColor;
- (NSString *)phoneNumber;
方法供實(shí)現(xiàn),接下來再創(chuàng)建一個(gè)基本的適配器類BusinessCardAdapter
,遵守BusinessCardAdapterProtocol
協(xié)議,并在頭文件里聲明一個(gè)屬性和一個(gè)構(gòu)造方法
@property (nonatomic, weak) id data; // 輸入對象
- (instancetype)initWithData:(id)data; // 與輸入對象建立聯(lián)系
在.m文件中實(shí)現(xiàn)如下代碼
- (instancetype)initWithData:(id)data{
self = [super init];
if (self) {
self.data = data;
}
return self;
}
- (NSString *)name{
return nil;
}
- (NSString *)phoneNumber{
return nil;
}
- (UIColor *)lineColor{
return nil;
}
現(xiàn)在新建一個(gè)模型文件叫作Model
,屬性如下
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *phoneNumber;
@property (nonatomic, strong) UIColor *lineColor;
再創(chuàng)建一個(gè)用來適配Model類的適配器ModelAdapter
繼承自基類適配器BusinessCardAdapter
,在.m文件里重載父類的方法如下
#import "Model.h"
#import "ModelAdapter.h"
@implementation ModelAdapter
- (instancetype)initWithData:(id)data{
self = [super init];
if (self) {
self.data = data;
}
return self;
}
- (NSString *)name{
Model *data = self.data;
return data.name;
}
- (UIColor *)lineColor{
Model *data = self.data;
return data.lineColor;
}
- (NSString *)phoneNumber{
Model *data = self.data;
return data.phoneNumber;
}
@end
這時(shí)候在我們的ViewController
里面這樣使用
// 創(chuàng)建UI控件
BusinessCardView *cardView = [[BusinessCardView alloc] initWithFrame:BUSINESS_FRAME]; cardView.center = self.view.center;
[self.view addSubview:cardView];
// 初始化模型
Model *model = [[Model alloc] init];
model.name = @"CoderRyan";
model.phoneNumber = @"188 - 8848 - 8848";
model.lineColor = [UIColor redColor];
// 與適配器連接
BusinessCardAdapter *adapter = [[ModelAdapter alloc] initWithData:model];
[cardView loadData:adapter];
cmd+R運(yùn)行,效果圖如下
假如現(xiàn)在有另外一個(gè)Model,需要適配,新建一個(gè)NewModel
類,包含如下屬性
#import <Foundation/Foundation.h>
@interface NewModel : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *hexColorString;
@property (nonatomic, copy) NSString *phoneNumber;
@end
這時(shí)候,同樣只需要新建一個(gè)繼承自基類適配器BusinessCardAdapter
,在.m文件里重載父類的方法如下
#import "NewCardModelAdapter.h"
#import "NewModel.h"
@implementation NewCardModelAdapter
- (instancetype)initWithData:(id)data
{
self = [super init];
if (self) {
self.data = data;
}
return self;
}
- (NSString *)name{
NewModel *model = self.data;
return model.name;
}
- (NSString *)phoneNumber{
NewModel *model = self.data;
return model.phoneNumber;
}
- (UIColor *)lineColor{
NewModel *model = self.data;
// TODO
if ([model.hexColorString isEqualToString:@"black"]) {
return [UIColor blackColor];
} else {
return [UIColor redColor];
}
}
@end
如果這時(shí)候想要在VC里面用新的適配器,只需要
// 與適配器連接
Model *model = [[Model alloc] init];
model.name = @"CoderRyan";
model.phoneNumber = @"188 - 8848 - 8848";
model.lineColor = [UIColor redColor];
BusinessCardAdapter *adapter = [[ModelAdapter alloc] initWithData:model];
[cardView loadData:adapter];
更改成
NewModel *newModel = [[NewModel alloc] init];
newModel.name = @"CoderRyan";
newModel.phoneNumber = @"188 - 8848 -8848";
newModel.hexColorString = @"black";
BusinessCardAdapter *adapter = [[NewCardModelAdapter alloc] initWithData:newModel];
[cardView loadData:adapter];
即可.
總結(jié)來說,就是在UI控件外部提供一個(gè)方法傳入實(shí)現(xiàn)了協(xié)議的屬性,外部根據(jù)一個(gè)模型來創(chuàng)建一個(gè)適配器,再通過與適配器連接.進(jìn)行更新UI.
優(yōu)點(diǎn):耦合度低,可以擴(kuò)展多種適配的樣式
缺點(diǎn):代碼量多,文件多.對于新手可能不理解這種好處.
以上是我對適配器模式的大致了解,上面的Demo是用極客學(xué)院的例子.如果有錯(cuò)漏之處,希望可以給我在下面評論留言給我指出,謝謝~