适配器模式:将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作,比如在一个view中,loadData时候,需要传入不同的model。
1115039-20190907181937147-1645261475.png第一种方式是类适配器模式
通过继承来适配两个接口,这称为类适配器。在OC中,类可以实现协议,同时又继承父类,达到C++多继承的效果。要在OC中实现类适配器,首先需要有定义了客户端要使用的一套行为的协议,然后要用具体的适配器类来实现这个协议。适配器类同时也要继承被适配者
Adapter是一个Target类型,同时也是Adaptee类型。它重载了Target的request方法,没有重载Adaptee中的specificRequest方法,而是在Adapter的request方法的实现中,调用父类的specificRequest方法。只有当Target是协议而不是类时,类适配器才能够用OC来实现,因为OC中是没有多重继承的
创建一个Adapter协议,里面包含我们需要用到的属性。
@protocol BusinessCardAdapterProtocol <NSObject>
- (NSString *)name;
- (UIColor *)lineColor;
- (NSString *)phoneNumber;
@end
创建一个Adapter基类,遵循BusinessCardAdapterProtocol协议,并实现协议中的方法。
@interface BusinessCardAdapter : NSObject <BusinessCardAdapterProtocol>
/**
* 输入对象
*/
@property (nonatomic, weak) id data;
/**
* 与输入对象建立联系
*
* @param data 输入的对象
*
* @return 实例对象
*/
- (instancetype)initWithData:(id)data;
@end
@implementation BusinessCardAdapter
- (instancetype)initWithData:(id)data {
self = [super init];
if (self) {
self.data = data;
}
return self;
}
- (NSString *)name {
return nil;
}
- (UIColor *)lineColor {
return nil;
}
- (NSString *)phoneNumber {
return nil;
}
@end
后面其实我们就可以创建涉及业务模块的Adapter类,继承自基类Adapter,自然是遵循了BusinessCardAdapterProtocol协议。然后在这里面,我们就可以针对不同的model来进行不同的处理。
@implementation CardAdapter
- (instancetype)initWithData:(id)data {
self = [super init];
if (self) {
self.data = data;
}
return self;
}
- (NSString *)name {
NSString *name = nil;
if ([self.data isMemberOfClass:[Model class]]) {
Model *model = self.data;
name = model.name;
} else if ([self.data isMemberOfClass:[NewCardModel class]]) {
NewCardModel *model = self.data;
name = model.name;
}
return name;
}
- (UIColor *)lineColor {
UIColor *lineColor = nil;
if ([self.data isMemberOfClass:[Model class]]) {
Model *model = self.data;
lineColor = model.lineColor;
} else if ([self.data isMemberOfClass:[NewCardModel class]]) {
NewCardModel *model = self.data;
if ([model.colorHexString isEqualToString:@"black"]) {
lineColor = [UIColor blackColor];
} else {
lineColor = [UIColor redColor];
}
}
return lineColor;
}
- (NSString *)phoneNumber {
NSString *phoneNumber = nil;
if ([self.data isMemberOfClass:[Model class]]) {
Model *model = self.data;
phoneNumber = model.phoneNumber;
} else if ([self.data isMemberOfClass:[NewCardModel class]]) {
NewCardModel *model = self.data;
phoneNumber = model.phoneNumber;
}
return phoneNumber;
}
@end
那么如何来使用适配器?
BusinessCardView *cardView = [[BusinessCardView alloc] initWithFrame:BUSINESS_FRAME];
cardView.center = self.view.center;
// 以对象赋值
Model *model = [[Model alloc] init];
model.name = @"1";
model.lineColor = [UIColor redColor];
model.phoneNumber = @"2";
NewCardModel *newCardModel = [[NewCardModel alloc] init];
newCardModel.name = @"4";
newCardModel.colorHexString = @"black";
newCardModel.phoneNumber = @"5";
// 与输入建立联系
BusinessCardAdapter *modelAdapter = [[CardAdapter alloc] initWithData:model];
// 与输出建立联系
[cardView loadData:modelAdapter];
// 如果data类型或者数据格式有变化,只需要在加一个适配器而已,而没有必要再vc里或者是View里增加逻辑代码,比如下面
// BusinessCardAdapter *newModelAdapter = [[CardAdapter alloc] initWithData:newCardModel];
// [cardView loadData:newModelAdapter];
[self.view addSubview:cardView];
在view中我们只需要loadData时,加入的数据都是遵循BusinessCardAdapterProtocol协议的类就可以了。
- (void)loadData:(id <BusinessCardAdapterProtocol>)data {
self.name = [data name];
self.lineColor = [data lineColor];
self.phoneNumber = [data phoneNumber];
}
第二种是对象适配器模式
Target和Adapter的关系相同,Adapter和Adaptee之间的关系,由继承变成了关联。这种关系下,Adapter需要保持一个对Adaptee的引用。在request方法中,Adapter发送[_adaptee specificRequest]消息给Adaptee,以完成客户端的请求
// 客户期望的协议接口
@protocol Target <NSObject>
- (void)request;
@end
// 适配对象
@interface Adapter : NSObject<Target>
{
Adaptee *_adaptee;
}
@end
@implementation Adapter
- (id)init
{
self = [super init];
if (self != nil)
{
_adaptee = [[Adaptee alloc] init];
}
return self;
}
- (void)request
{
[_adaptee specificRequest];
}
@end
// 被适配的对象
@interface Adaptee : NSObject
- (void)specificRequest;
@end
@implementation Adaptee
- (void)specificRequest
{
NSLog(@"specificRequest");
}
@end
使用
id<Target> target = [[Adapter alloc] init];
[target request];
网友评论