
适配器模式有两种:
1.类适配器
2.对象适配器
一、类适配器
适配器Adapter通过继承被适配对象Adaptee来适配两个接口。

实例讲解
最常用的例子:美元转人民币
1.目标接口
@protocol TargetCNYProtocol <NSObject>
// 转化后的人民币
- (float)getCNY;
@end
2.适配对象
@interface AdapteeUSD : NSObject
- (float)getUSD;
@implementation AdapteeUSD
- (float)getUSD {
return 100;
}
@end
3.适配器继承适配对象
@interface AdapterCNY : AdapteeUSD <TargetCNYProtocol>
@end
@implementation AdapterCNY
- (float)getCNY {
return [self getUSD] * 6.61f;
}
@end
4.调用
AdapterCNY *adapterCNY = [[AdapterCNY alloc] init];
float cny = [adapterCNY getCNY];
NSLog(@"cny: %.2f", cny);
二、对象适配器
适配器Adapter不继承被适配对象Adaptee, 他们是一个关联关系,
相当于引用了这个类。

我们在开发项目时经常会遇到这种情况,视图里持有一个model,让model给视图里的控件赋值,比如:
@interface ColorView : UIView
@property (nonatomic, strong)Model *model;
@end
@interface Model : NSObject
@property (nonatomic, strong) UIColor *smallViewColor; /**< 颜色 */
@property (nonatomic, copy) NSString *userName; /**< 用户名 */
@property (nonatomic, copy) NSString *password; /**< 密码 */
@end
但是当外部传来新的不一样的NewModel时就无法再套用:
@interface NewModel : NSObject
@property (nonatomic, strong) NSString *smallViewColor; /**< 颜色 */
@property (nonatomic, copy) NSString *userName; /**< 用户名 */
@property (nonatomic, copy) NSString *password; /**< 密码 */
@end
可以看出视图跟model需要解耦。我们需要定义一个统一的接口,这个接口根据视图要显示的内容规定出统一口径,那外部传给视图的model可能不同,就需要根据这个统一口径来进行适配。
根据视图上的内容,这个接口是:
// 目标接口
@protocol TargeyProtocol <NSObject>
- (UIColor *)smallViewColor; /**< 颜色 */
- (NSString *)UserName; /**< 用户名 */
- (NSString *)password; /**< 密码 */
@end
抽象适配器:
#import <UIKit/UIKit.h>
#import "TargeyProtocol.h"
@interface ColorViewAdapter : NSObject <TargeyProtocol>
@property (nonatomic, strong) id model; /**< 输入的模型数据 */
- (instancetype)initWithModel:(id)model; /**< 初始化的一个方法 */
@end
@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
NewModelAdapter:
#import "ColorViewAdapter.h"
@interface NewModelAdapter : ColorViewAdapter
@end
@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
而视图中只需有个遵循接口的model即可:
#import "TargeyProtocol.h"
@interface ColorView : UIView
- (void)loadModel:(id <TargeyProtocol>)model;
@end
实现:
#import "ColorView.h"
@interface ColorView ()
@property (nonatomic, strong) UIView *smallView;
@property (nonatomic, strong) UILabel *userLabel;
@property (nonatomic, strong) UILabel *pswLabel;
@end
@implementation ColorView
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self setupUI];
}
return self;
}
// 添加UI
- (void)setupUI {
// 灰色的view
self.backgroundColor = [UIColor lightGrayColor];
CGFloat width = self.bounds.size.width;
self.smallView = [[UIView alloc] initWithFrame:CGRectMake(0, 60, width,200)];
[self addSubview:self.smallView];
// 用户名
self.userLabel = [[UILabel alloc] initWithFrame:CGRectMake(130, 100, 150, 25)];
[self addSubview:self.userLabel];
// 密码
self.pswLabel = [[UILabel alloc] initWithFrame:CGRectMake(130, 130, 150, 25)];
[self addSubview:self.pswLabel];
}
// 给属性赋值
- (void)loadModel:(id <TargeyProtocol>)model {
self.pswLabel.text = model.password;
self.userLabel.text = model.UserName;
self.smallView.backgroundColor = model.smallViewColor;
}
@end
调用:
- (void)viewDidLoad {
[super viewDidLoad];
ColorView *colorView = [[ColorView alloc] initWithFrame:self.view.bounds];
// 赋值模型
NewModel *model = [[NewModel alloc] init];
model.smallViewColor = @"blue";
model.userName = @"张三";
model.password = @"1-1-1-1";
NewModelAdapter *newModelAdapter = [[NewModelAdapter alloc] initWithModel:model];
[colorView loadModel:newModelAdapter];
// 添加
[self.view addSubview:colorView];
}
可以看出,view跟model通过适配器解耦了,无论外部传的是哪个model,只要它遵循接口就可以了。
网友评论