适配器是为了 兼容不同Model的API,适配器通过代理形成统一的属性props
一、定义一个协议
#import <Foundation/Foundation.h>
@protocol BusinessCardAdapterProtocol <NSObject>
- (NSString *)name;
- (UIColor *)lineColor;
- (NSString *)phoneNumber;
@end
二、定义业务适配器
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "BusinessCardAdapterProtocol.h"
NS_ASSUME_NONNULL_BEGIN
@interface BussinessCardAdapterV2 : NSObject<BusinessCardAdapterProtocol>
@property (nonatomic, weak) id data;
- (instancetype)initWithData:(id)data;
@end
NS_ASSUME_NONNULL_END
#import "BussinessCardAdapterV2.h"
@implementation BussinessCardAdapterV2
- (instancetype)initWithData:(id)data{
if (self = [super init]) {
self.data = data;
}
return self;
}
- (NSString *)name {
return nil;
}
- (UIColor *)lineColor{
return nil;
}
- (NSString *)phoneNumber {
return nil;
}
@end
三、继承业务适配器创建具体适配器
#import "BussinessCardAdapterV2.h"
NS_ASSUME_NONNULL_BEGIN
@interface CardAdapterV2 : BussinessCardAdapterV2
@end
NS_ASSUME_NONNULL_END
#import "CardAdapterV2.h"
#import "Model.h"
#import "NewCardModel.h"
@implementation CardAdapterV2
- (instancetype)initWithData:(id)data{
if (self = [super init]) {
self.data = data;
}
return self;
}
- (NSString *)name{
NSString* name = nil;
/*
isKindOfClass: Returns a Boolean value that indicates whether the receiver is an instance of given class or an instance of any class that inherits from that class. isMemberOfClass: Returns a Boolean value that indicates whether the receiver is an instance of a given class.
*/
/*
isMemberOfClass 就是很明确的判断data是否是Model的实例 isKindOfClass 范围就大了 包括该类的实例和葱该继承的类
*/
if ([self.data isMemberOfClass:[Model class]]) {
Model *model = self.data;
name = model.name;
}else if([self.data isMemberOfClass:[NewCardModel class]]){
NewCardModel *mode = self.data;
name = mode.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
四、业务UI 控件加载适配器
BusinessCardView *cardView = [[BusinessCardView alloc] initWithFrame:BUSINESS_FRAME];
cardView.center = self.view.center;
// 直接赋值 这样做确实很简单粗暴,优缺点我也在简书中提示了,各自斟酌。
// cardView.name = @"JiKeXueYuan";
// cardView.lineColor = [UIColor redColor];
// cardView.phoneNumber = @"101 - 5687 - 000";
// 以对象赋值
Model *model = [[Model alloc] init];
model.name = @"wupeng";
model.lineColor = [UIColor redColor];
model.phoneNumber = @"101 - 5687 - 000";
NewCardModel *newCardModel = [[NewCardModel alloc] init];
newCardModel.name = @"wupeng";
newCardModel.colorHexString = @"black";
newCardModel.phoneNumber = @"123 - 4567 - 891";
// 与输入建立联系
BussinessCardAdapterV2 *modelAdapter = [[CardAdapterV2 alloc] initWithData:model];
// 与输出建立联系
[cardView loadData:modelAdapter];
- (void)loadData:(id <BusinessCardAdapterProtocol>)data {
self.name = [data name];
self.lineColor = [data lineColor];
self.phoneNumber = [data phoneNumber];
}
五、总结
-
如何使用适配器模式?
以下情况比较适合使用 Adapter 模式:
- 当你想使用一个已经存在的类,而它的接口不符合你的需求;
- 你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类协同工作;
- 你想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口,对象适配器可以适配它的父亲接口。
-
适配器模式的优缺点?
优点:降低数据层和视图层(对象)的耦合度,使之使用更加广泛,适应复杂多变的变化。
缺点:降低了可读性,代码量增加,对于不理解这种模式的人来说比较难看懂。