今天要介绍的是适配器模式(Adapter Pattern)
,适配器模式又叫做变压器模式
,也叫做包装模式(Wrapper)
,但是包装模式
却不止一个,装饰模式
也是包装模式
,以后会介绍到。适配器模式是一种补救模式,他可以让你从因业务扩展而系统无法迅速适应的苦恼中解脱出来。我们在进行系统开发时,不管之前的可行性分析、需求分析、系统设计处理的多么完美,总会在关键时候、关键场合出现一些“意外”。这些“意外”,该来的还是要来,躲是躲不过的,而这时就是我们的适配器模式
的用武之地。适配器模式
最好在设计阶段不要考虑它,它不是为了解决还处在开发阶段的问题,而是解决正在服役的项目问题,没有一个系统分析师会再做详细设计时考虑使用适配器模式
。
适配器模式
包含两种,一种是类适配器
,另一种是对象适配器
。类适配器
是通过类的继承实现的适配,而对象适配器
是通过对象间的关联关系,组合关系实现的适配。二者在实际项目中都会经常用到,由于对象适配器
是通过类间的关联关系进行耦合的,因此在设计时就可以做到比较灵活,而类适配器
就只能通过覆写源角色的方法进行拓展,在实际项目中,对象适配器
使用到的场景相对较多。在iOS
开发中也推荐多使用组合关系,而尽量减少继承关系,这是一种很好的编程习惯,因此我在这里只介绍对象适配器
,想了解更多的关于类适配器
的话,请自行Google
之。
适配器模式定义
Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces.(将一个类的接口变成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。)
适配器模式类图
适配器模式说明
Target目标角色
该角色定义把其他类转换为何种接口,也就是我们的期望接口。
Adaptee源角色
你想把“谁”转换成目标角色,这个“谁”就是源角色,它是已经存在的、运行良好的类或对象。
Adapter适配器角色
适配器模式的核心角色,其他两个角色都是已经存在的角色,而适配器角色是需要新建立的,他的职责非常简单:把源角色转换为目标角色。
适配器模式优点
适配器模式可以让两个没有任何关系的类在一起运行,只要适配器这个角色能够搞定他们就成。
增加了类的透明性。我们访问的是目标角色,但是实现却在源角色里。
提高了类的复用度。源角色在原有系统中还是可以正常使用的。
灵活性非常好。不想要适配器时,删掉这个适配器就好了,其他代码不用改。
适配器模式的objective-C实现
Target
1
2
3
4
5
6
7
#import <Foundation/Foundation.h>
@protocol Target < NSObject >
- ( void ) userExpectInterface ;
@end
Adaptee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#import <Foundation/Foundation.h>
@interface Adaptee : NSObject
- ( void ) doSometing ;
@end
@implementation Adaptee
- ( void ) doSometing
{
NSLog ( @"adaptee doing something!" );
}
@end
Adapter
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
#import "Target.h"
#import "Adaptee.h"
@interface Adapter : NSObject < Target >
@property ( strong , nonatomic ) Adaptee * adaptee ;
- ( id ) initWithAdaptee: ( Adaptee * ) adaptee ;
@end
@implementation Adapter
@synthesize adaptee = _adaptee ;
- ( id ) initWithAdaptee: ( Adaptee * ) adaptee
{
if ( self = [ super init ]) {
_adaptee = adaptee ;
}
return self ;
}
- ( void ) userExpectInterface
{
[ self . adaptee doSometing ];
}
@end
main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#import <Foundation/Foundation.h>
#import "Adapter.h"
#import "Adaptee.h"
#import "Target.h"
int main ( int argc , const char * argv [])
{
@autoreleasepool {
Adaptee * adaptee = [[ Adaptee alloc ] init ];
id < Target > object = [[ Adapter alloc ] initWithAdaptee : adaptee ];
[ object userExpectInterface ];
}
return 0 ;
}