原文出处: Lastdays(@Lastday_s) 编程
很好奇,什么是适配器,你们有没有据说过电源适配器,其实原理都是同样的,就是说咱们的iPhone手机,在中国,能够用iPhone充电器给手机充电,都知道,中国的电压是220V,对吧,咱们的iPhone额定输入电压是5V,其实这就是咱们适配器的功劳,并且,咱们的充电器在中国能用,固然若是咱们去了美国,没过不是220V,难道咱们的手机就不能充电了吗?固然确定不会,总结来讲:在计算机编程中,适配器模式(有时候也称包装样式或者包装)将一个类的接口适配成用户所期待的。一个适配容许一般由于接口不兼容而不能在一块儿工做的类工做在一块儿,作法是将类本身的接口包裹在一个已存在的类中。bash
最简单明了就是直接写一个示例来讲名测试
制做一张卡片:atom
对卡片的数据直接赋值:spa
Objective-C.net
1设计 2orm 3对象 4继承 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
#import "ViewController.h" #import "BusinessCard.h"
@interface ViewController ()
@implementation ViewController
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib.
BusinessCard *card = [[BusinessCard alloc] initWithFrame:BUSINESS_FRAME]; card.name = @"姓名"; card.color = [UIColor blueColor]; card.phoneNumber = @"电话";
card.center = self.view.center;
[self.view addSubview:card];
}
- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; }
@end |
运行结果:
很是简单的一个示例,这基本上就是咱们之前常用的一种方法直接赋值,这种的缺点,其实很简单,就是耦合性太强了,简简单单的移除更改,可能就会形成不少地方进行更改。如今看起来很简单就更改,可是若是咱们的数据不少不少呢?
所以咱们如今简单的来改进一下,设计一个model。而且在BusinessCard添加以下代码:
Objective-C
1 2 3 4 5 6 7 8 9 10 |
/** * 初始化数据 * * @param model BusinessCard */ -(void)loadDataWithModel:(Model *)model{ self.name = model.name; self.phoneNumber = model.phoneNumber; self.line = model.lineColor; } |
ViewController:
Objective-C
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib Model *model = [[Model alloc] initWithName:@"lastdays" phoneNumber:@"158******1111" lineColor:[UIColor blueColor]]; BusinessCard *card = [[BusinessCard alloc] initWithFrame:BUSINESS_FRAME]; card.center = self.view.center; [card loadDataWithModel:model]; [self.view addSubview:card]; }
- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } @end |
这样就下降了一些耦合性,这就是以对象形式赋值。
可是咱们如今来阐述一个很致命的问题,那就是若是咱们来了一个新的Model数据类型,其中的UIcolor是二进制形的。跟咱们原来处理的数据类型不符合?这个时候怎么办?
其实解决方案很简单,这也就是上面提到过的,电源适配器原理。
电源有输入和输出,固然咱们先来构建适配器
CardAdapterProtocol:
Objective-C
1 2 3 4 5 6 7 8 9 10 11 12 |
#import <Foundation/Foundation.h> #import <UIKit/UIKit.h>
@protocol CardAdapterProtocol <NSObject>
- (NSString *)name;
- (UIColor *)lineColor;
- (NSString *)phoneNumber;
@end |
CardAdapter:
Objective-C
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
#import <Foundation/Foundation.h> #import "CardAdapterProtocol.h" #import <UIKit/UIKit.h>
@interface CardAdapter : NSObject<CardAdapterProtocol>
/** * 创建输入关系 */ @property(nonatomic,weak) id data;
/** * 与输入对象创建联系 * * @param data 输入的对象 * * @return 当前实例对象 */ - (instancetype)initWithModel:(id)data;
@end ```
``` bash #import "CardAdapter.h"
@implementation CardAdapter
- (NSString *)name{ return nil; }
- (UIColor *)lineColor{ return nil; }
- (NSString *)phoneNumber{ return nil; }
@end |
这里咱们构建了CardAdapterProtocol协议,以及抽象类CardAdapter,接下来就是建立ModelCardAdapter,这就是针对Model构建的适配器,而后覆盖内部方法进行重写。
这里须要作一下说明CardAdapter中经过initWithModel创建与Model的输入关系,就是咱们在国内用充电器给手机充电,CardAdapter与Model的关系就是充电器跟220V电压的关系。
接下来就该创建充电器跟手机的关系了,这里面至关于构建CardAdapter和View的关系。
BusinessCard
Objective-C
1 2 3 4 5 6 7 8 9 10 |
/** * 初始化卡片数据 * * @param model BusinessCard */ -(void)loadDataWithModel:(id<CardAdapterProtocol>)data{ self.name = [data name]; self.phoneNumber = [data phoneNumber]; self.line = [data lineColor]; } |
这样,咱们基本上就完成了构建,测试:
ViewController:
Objective-C
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
#import "ViewController.h" #import "BusinessCard.h" #import "Model.h" #import "ModelCardAdapter.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib.
Model *model = [[Model alloc] initWithName:@"lastdays" phoneNumber:@"158******1111" lineColor:[UIColor blueColor]];
//创建充电器跟电源关系 CardAdapter *cardAdapter = [[ModelCardAdapter alloc] initWithModel:model];
BusinessCard *card = [[BusinessCard alloc] initWithFrame:BUSINESS_FRAME]; card.center = self.view.center;
//创建手机跟充电器关系 [card loadDataWithModel:cardAdapter]; [self.view addSubview:card]; }
- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; }
@end |
测试结果:
以上咱们使用的就是类适配器,固然还有一种叫作对象适配器,就是说不管咱们是220V,仍是100V,用这一个充电器都能给手机充电。这种如何实现?简单的说就是咱们能够构建一个Adapter继承CardAdapter,简单的举个例子
Adapter
Objective-C
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
- (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; } |
根绝对象类型进行判断返回哪一种处理结果。这种其实并不推荐,由于什么?由于如今的数据模型比较少,若是有10个,20个数据模型,那这个类到最好会很是的臃肿,并不方便咱们维护。
优势显而易见,就是让适配器可让咱们的View更增强大,能够适配不一样的数据,下降咱们的耦合性
其实在代码中就能够看出来,一个简单赋值的东西,用了这么多东西,比较麻烦,有的时候是很繁琐的。可是呢?话又说回来,咱们若是作了一个很牛的控件,为了提升它的通用性,加一个适配器会更好一些。 当咱们的代码能力增长。可是呢? 这一样也是一个缺点,那就是代码的可读性很差。这点的权衡就靠本身来衡量,虽然麻烦一些,可是确实可以提升扩展性 QQ技术交流群290551701