适配器模式分为类适配器与对象适配器两种:
适配器模式UML图
类适配器:继承关系(被适配的类和类适配器是继承关系)
对象适配器:不是继承关系,是单向关联关系
例子:
美元转换为人民币
创建被适配的类AdapteeUSD
AdapteeUSD.h
#import <Foundation/Foundation.h>
// 要适配的一个对象
@interface AdapteeUSD : NSObject
//美元
- (float)getUSD;
@end
AdapteeUSD.m
#import "AdapteeUSD.h"
@implementation AdapteeUSD
- (float)getUSD {
return 100;
}
@end
思路: 美元适配者已经准备好, 对人民币进行适配. 准备目标接口
目标接口准备好后, 新建一个适配器去进行实现实现需求
新建一个协议类TargetCNYProtocol
#import <Foundation/Foundation.h>
// 目标接口
@protocol TargetCNYProtocol <NSObject>
// 转化后的人民币
- (float)getCNY;
@end
创建一个适配器AdapterCNY,继承自被适配的对象AdapteeUSD
AdapterCNY.h
#import "AdapteeUSD.h"
#import "TargetCNYProtocol.h"
@interface AdapterCNY : AdapteeUSD <TargetCNYProtocol>
@end
AdapterCNY.m
#import "AdapterCNY.h"
// 适配器
@implementation AdapterCNY
- (float)getCNY {
return [self getUSD] * 6.61f;
}
@end
ViewController调用
#import "ViewController.h"
#import "AdapterCNY.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 类适配器
AdapterCNY *adapterCNY = [[AdapterCNY alloc] init];
float cny = [adapterCNY getCNY];
NSLog(@"cny: %.2f", cny);
}
@end
输出:2018-06-04 14:41:42.049047+0800 AdapterCNY[4925:199623] cny: 661.00
100美金转换为661人民币
对象适配器
创建一个ObjectAdapter类
ObjectAdapter.h
#import <Foundation/Foundation.h>
#import "TargetCNYProtocol.h"
#import "AdapteeUSD.h"
@interface ObjectAdapter : NSObject <TargetCNYProtocol>
- (instancetype)initWithAdaptee:(AdapteeUSD *)adaptee;
@end
ObjectAdapter.m
#import "ObjectAdapter.h"
@interface ObjectAdapter ()
@property (nonatomic, strong) AdapteeUSD *adapteeUSD;
@end
@implementation ObjectAdapter
- (instancetype)initWithAdaptee:(AdapteeUSD *)adaptee {
self = [super init];
if (self) {
_adapteeUSD = adaptee;
}
return self;
}
- (float)getCNY {
return [self.adapteeUSD getUSD] * 6.61f;
}
@end
ViewController调用对象适配器
#import "ViewController.h"
#import "AdapterCNY.h"
#import "ObjectAdapter.h"
#import "AdapteeUSD.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// 类适配器
AdapterCNY *adapterCNY = [[AdapterCNY alloc] init];
float cny = [adapterCNY getCNY];
NSLog(@"cny: %.2f", cny);
// 对象适配器
ObjectAdapter *adapterOCNY = [[ObjectAdapter alloc] initWithAdaptee:[AdapteeUSD new]];
float cny2 = [adapterOCNY getCNY];
NSLog(@"CNY:%.2f",cny2);
}
@end
类适配器: 通过继承来适配两个接口
对象适配器: 不继承被适配者, 他们是一个关联关系,
相当于引用了这个类
示例2
我们再看一个示例:
创建一个简单的模型
Model.h
#import <UIKit/UIKit.h>
@interface Model : NSObject
@property (nonatomic, strong) UIColor *smallViewColor; /**< 颜色 */
@property (nonatomic, copy) NSString *userName; /**< 用户名 */
@property (nonatomic, copy) NSString *password; /**< 密码 */
@end
创建ColorView类
ColorView.h
#import <UIKit/UIKit.h>
#import "Model.h"
@interface ColorView : UIView
@end
ColorView.m
#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)setModel:(Model *)model{
self.userLabel.text = model.password;
self.pswLabel.text = model.userName;
self.smallView.backgroundColor = model.smallViewColor;
}
@end
ViewController调用
#import "ViewController.h"
#import "ColorView.h"
#import "Model.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
ColorView *colorView = [[ColorView alloc] initWithFrame:self.view.bounds];
// 赋值模型
Model *model = [[Model alloc] init];
model.smallViewColor = [UIColor blueColor];
model.userName = @"张三";
model.password = @"1-1-1-1";
colorView.model = model;
// 添加
[self.view addSubview:colorView];
}
@end
这是我们正常的使用方式,但是我们在平时开发中经常遇见的是后台服务器给我们的数据格式有个别时候是不固定的,例如UIColor类型smallViewColor,后台传入一个NSString类型的数据。这种情况如果用适配器模式应该怎么解决呢?
创建一个新模型NewModel
NewModel.h
#import <Foundation/Foundation.h>
@interface NewModel : NSObject
@property (nonatomic, strong) NSString *smallViewColor; /**< 颜色 */
@property (nonatomic, copy) NSString *userName; /**< 用户名 */
@property (nonatomic, copy) NSString *password; /**< 密码 */
@end
创建协议类TargeyProtocol
TargeyProtocol.h
#import <Foundation/Foundation.h>
// 目标接口
@protocol TargeyProtocol <NSObject>
- (UIColor *)smallViewColor; /**< 颜色 */
- (NSString *)userName; /**< 用户名 */
- (NSString *)password; /**< 密码 */
@end
创建ColorViewAdapter类
ColorViewAdapter.h
#import <UIKit/UIKit.h>
#import "TargeyProtocol.h"
@interface ColorViewAdapter : NSObject <TargeyProtocol>
@property (nonatomic, strong) id model; /**< 输入的模型数据 */
- (instancetype)initWithModel:(id)model; /**< 初始化的一个方法 */
@end
ColorViewAdapter.m
#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
创建NewModelAdapter类
NewModelAdapter.m
#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
ViewController调用
#import "ViewController.h"
#import "ColorView.h"
#import "NewModel.h"
#import "NewModelAdapter.h"
//#import "Model.h"
@interface ViewController ()
@end
@implementation ViewController
- (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";
// colorView.model = model;
NewModelAdapter *newModelAdapter = [[NewModelAdapter alloc] initWithModel:model];
[colorView loadModel:newModelAdapter];
// 添加
[self.view addSubview:colorView];
}
@end