原文出处: Lastdays(@Lastday_s)
很好奇,什么是适配器,大家有没有听说过电源适配器,其实原理都是一样的,就是说我们的iPhone手机,在中国,可以用iPhone充电器给手机充电,都知道,中国的电压是220V,对吧,我们的iPhone额定输入电压是5V,其实这就是我们适配器的功劳,而且,我们的充电器在中国能用,当然如果我们去了美国,没过不是220V,难道我们的手机就不能充电了吗?当然肯定不会,总结来说:在计算机编程中,适配器模式(有时候也称包装样式或者包装)将一个类的接口适配成用户所期待的。一个适配允许通常因为接口不兼容而不能在一起工作的类工作在一起,做法是将类自己的接口包裹在一个已存在的类中。

为何使用适配器?

直接赋值的缺点

最简单明了就是直接写一个示例来说名

制作一张卡片:

对卡片的数据直接赋值:

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

#import "ViewController.h"
#import "BusinessCard.h"
@interface ViewController ()
@end
@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

http://cxy.liuzhihengseo.com/524.html

转载于:https://www.cnblogs.com/8hao/p/5383234.html

iOS设计模式-适配器相关推荐

  1. iOS设计模式四部曲(二) 结构型模式 内附Demo

    本篇是四部曲的第二篇,第一篇请点这里iOS设计模式四部曲(一):创建型模式 内附Demo,关于设计模式强烈推荐图书<Head First设计模式>以及<研磨设计模式>.由于个人 ...

  2. iOS设计模式 - 生成器

    iOS设计模式 - 生成器 原理图 说明 1. 将构建复杂对象的过程拆分成一个一个的模块,通过统一的指导者来指导对象的构建过程称之为生成器模式 2. 生成器模式适合用于构建组合的对象 源码 https ...

  3. iOS设计模式四部曲(三):行为型模式 内附Demo

    本篇是四部曲的第三篇,第一篇请点这里iOS设计模式四部曲(一):创建型模式,第二篇请点击这里iOS设计模式四部曲(二):结构型模式.由于个人能力有限,文中难免有一些遗漏或者错误,请各位看官不吝赐教!谢 ...

  4. iOS设计模式 - 备忘录

    iOS设计模式 - 备忘录 原理图 说明 1. 在不破坏封装的情况下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样以后就可以将该对象恢复到原先保存的状态 2. 本人已经将创建状态与恢复状态 ...

  5. iOS设计模式 - 组合

    iOS设计模式 - 组合 原理图 说明 将对象组合成树形结构以表示"部分-整体"的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性.掌握组合模式的重点是要理解清楚 & ...

  6. Go 语言实现 23 种设计模式适配器

    Go 语言实现 23 种设计模式适配器 将一个类型的接口转换成客户希望的另外一个接口,使原本由于接口不兼容而不能一起工作的类可以一起工作. Example_one package mainimport ...

  7. iOS设计模式 - 享元

    iOS设计模式 - 享元 原理图 说明 享元模式使用共享物件,用来尽可能减少内存使用量以及分享资讯给尽可能多的相似物件:它适合用于只是因重复而导致使用无法令人接受的大量内存的大量物件.通常物件中的部分 ...

  8. iOS设计模式 - 迭代器

    iOS设计模式 - 迭代器 原理图 说明 提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示. 源码 https://github.com/YouXianMing/iOS-Des ...

  9. 设计模式---适配器设计模式

    设计模式---适配器设计模式 什么事适配器: 1. 在使用监听的时候,需要定义一个类事件监听器接口 2. 通常接口中有多个方法,而程序中不一定所有的方法都用到,但又必须重写,很繁琐 3. 适配器简化了 ...

最新文章

  1. python怎么画函数图_可视化|Python绘制桑基图
  2. 前沿科技山雨欲来,四大领域存创新机会
  3. mybaits二十三:二级缓存
  4. Swift2.0 中的String(一):常用属性
  5. IDEA 2019.2版本下载安装与PJ教程
  6. 使用 ABAP Open SQL 的 Select AS 别名,提高代码可读性
  7. 发现一个小坑的地方,unity的协程,想要停止,必须以字符串启动
  8. P5502 [JSOI2015]最大公约数(gcd性质/min性质/分治)
  9. git pull和push整理和归纳
  10. Linux的crond的配置流程,Linux之定时任务Crond详解
  11. 时间序列-N_LSTM
  12. VMware windows xp虚拟机设置静态ip
  13. Java工程师的职业规划,上个月成功拿到阿里P7offer
  14. UOJ【UR #12】实验室外的攻防战 题解
  15. spss对数据进行聚类分析(系统聚类法和k-均值聚类法)和判别分析(费歇尔和贝叶斯)。
  16. Word文档中X的平方怎么打出来?
  17. android 记录触屏坐标,android触摸屏坐标手工校准/调整成功
  18. python批量修改文件名字为1,2,3,4,5等等
  19. 【OpenGL ES】二维图形绘制
  20. 带通 带阻滤波器 幅频响应_滤波器原理,各式尽在掌握

热门文章

  1. eclipse中添加svn插件
  2. centos6.5 最小化安装无法上网
  3. JAVA中Math类的random()方法使用
  4. 关于JSTL的简单说明
  5. 同步、异步事件循环(宏任务、微任务「大厂真题解析」)
  6. Vue:You may use special comments to disable some warnings.
  7. 大学生必须要知道的毕业设计基本流程
  8. CCF CSP201903-2二十四点
  9. 活动地推怎么做最有效?
  10. 几个好朋友在一起吃饭,结账时大家都抢着买单,你会怎么做?