概念
适配器就是一种适配中间件,它存在于不匹配的二者之间,用于连接二者,将不匹配变得匹配,简单点理解就是平常所见的转接头,转换器之类的存在。
适配器模式有两种:类适配器、对象适配器
1.类适配器: 适配器是继承自适配者的
2. 对象适配器 : 适配器是引用适配者的
类适配器
这里写图片描述
对象适配器
这里写图片描述
demo
需求说明,做一个适配器适配人民币和美元
这里写图片描述
被适配的美元
#import <Foundation/Foundation.h>
// 要适配的对象
@interface AdapteeUSD : NSObject
// 美元
- (float)getUSD;
@end
#import "AdapteeUSD.h"
@implementation AdapteeUSD
- (float)getUSD {
return 100;
}
@end
接口协议文件
#import <Foundation/Foundation.h>
// 目标接口
@protocol TargetCNYProtocol <NSObject>
// 转化后的人民币
- (float)getCNY;
@end
类适配器是继承关系
@interface AdapterCNY : AdapteeUSD <TargetCNYProtocol>
@end
@implementation AdapterCNY
- (float)getCNY {
return [self getUSD] * 6.61f;
}
@end
对象适配器是关联关系,所以要有一个属性
#import "TargetCNYProtocol.h"
#import "AdapteeUSD.h"
@interface ObjectAdapter : NSObject <TargetCNYProtocol>
- (instancetype)initWithAdapter:(AdapteeUSD *)adaptee;
@end
@interface ObjectAdapter ()
@property (nonatomic, strong) AdapteeUSD *adapteeUSD;
@end
@implementation ObjectAdapter
- (instancetype)initWithAdapter:(AdapteeUSD *)adaptee {
self = [super init];
if (self) {
_adapteeUSD = adaptee;
}
return self;
}
- (float)getCNY {
return [self.adapteeUSD getUSD] * 6.61f;
}
@end
viewcontroller调用
- (void)viewDidLoad {
[super viewDidLoad];
// 类适配器
AdapterCNY *adapterCNY = [[AdapterCNY alloc] init];
float cny = [adapterCNY getCNY];
NSLog(@"CNY = %.2f", cny);
// 对象适配器
ObjectAdapter *adatperObjCNY = [[ObjectAdapter alloc] initWithAdapter:[AdapteeUSD new]];
float cny2 = [adatperObjCNY getCNY];
NSLog(@"adatperObjCNY = %.2f", cny2);
}
demo2
这个demo比较容易看出适配器模式的好处。
在平时开发中,都要这样的需求,比如一个方法,原来传入的一个model。后面有了新需求,要求传入的model变了。这种情况,就可以用适配器模式,将我们的改动量降低。如下。
ColorView接收的是一个Model类型,后面新需求是增加一个新的NewModel。
来用适配器模式适配。
1.创建model的适配器协议
@protocol TargetProtocol <NSObject>
- (UIColor *)smallViewColor; /**< 颜色 */
- (NSString *)userName; /**< 用户名 */
- (NSString *)password; /**< 密码 */
@end
2.讲ColorView的传入model修改为符合协议的model
@interface ColorView : UIView
// 加载的数据, 已经实现了TargetProtocol里面的要求
- (void)loadModel:(id <TargetProtocol>)model;
@end
3.创建适配器
#import "TargetProtocol.h"
@interface ColorViewAdapter : NSObject <TargetProtocol>
@property (nonatomic, strong) id model; /**< 输入的模型数据 */
- (instancetype)initWithModel:(id)model; /**< 初始化的方法 */
@end
#import "ColorViewAdapter.h"
@implementation ColorViewAdapter
- (instancetype)initWithModel:(id)model {
self = [super init];
if (self) {
self.model = model;
}
return self;
}
- (UIColor *)smallViewColor {
return nil;
}
- (NSString *)userName {
return nil;
}
- (NSString *)password {
return nil;
}
@end
比如增加的newModel,就可以创建NewModelAdapter适配器集成ColorViewAdapter,重写协议的方法
#import "ColorViewAdapter.h"
@interface NewModelAdapter : ColorViewAdapter
@end
import "NewModelAdapter.h"
#import "NewModel.h"
@implementation NewModelAdapter
- (UIColor *)smallViewColor {
NewModel *model = self.model;
// 如果外界传的是字符串, 就做逻辑判断
if ([model.smallViewColor isEqualToString:@"blue"]) {
return [UIColor blueColor];
} else {
return [UIColor redColor];
}
}
- (NSString *)userName {
NewModel *model = self.model;
return model.userName;
}
- (NSString *)password {
NewModel *model = self.model;
return model.password;
}
@end
4.调用
// 赋值的NewModel
NewModel *newModel = [[NewModel alloc] init];
newModel.smallViewColor = @"blue";
newModel.userName = @"张三";
newModel.password = @"1-1-1-1";
id<TargetProtocol> newModelAdapter = [[NewModelAdapter alloc] initWithModel:newModel];
[colorView loadModel:newModelAdapter];
// 添加
[self.view addSubview:colorView];
这样后面如果要增加新的model,只需要新写一个ColorViewAdapter的适配器子类就行了,改动量很低
PS
tableView也是用了我们的适配器模式
目标接口 UITableViewDataSource,UITableViewDelegate
适配器: Controller
数据: 适配者.数据转化成了UI
与桥接模式区别
- 适配器: 改变已有的两个接口, 让他们相互兼容. (组件之间的适配, 音视频方面, SDK跟自己写的代码之间适配)
桥接模式: 分离抽象化和实现类. 两者的接口可以不同, 主要是在于分离 - 桥接模式先有桥, 才有两段的实现.
适配器模式是先有两边的,才有适配器.
网友评论