首页 > 代码库 > 设计模式【6】:适配器模式【接口适配】

设计模式【6】:适配器模式【接口适配】

objective-c中使用实施适配器模式的时候使用的是协议

适配器模式(Adapter Pattern),适配器模式又叫做变压器模式,也叫做包装模式(Wrapper),可是包装模式却不止一个,装饰模式也是包装模式。适配器模式是一种补救模式,他能够让你从因业务扩展而系统无法迅速适应的苦恼中解脱出来。我们在进行系统开发时,无论之前的可行性分析、需求分析、系统设计处理的多么完美,总会在关键时候、关键场合出现一些“意外”。这些“意外”,该来的还是要来,躲是躲只是的,而这时就是我们的适配器模式的用武之地。适配器模式最好在设计阶段不要考虑它,它不是为了解决还处在开发阶段的问题,而是解决正在服役的项目问题,没有一个系统分析师会再做具体设计时考虑使用适配器模式

适配器模式包括两种,一种是类适配器,还有一种是对象适配器类适配器是通过类的继承实现的适配,而对象适配器是通过对象间的关联关系,组合关系实现的适配。二者在实际项目中都会经经常使用到,因为对象适配器是通过类间的关联关系进行耦合的,因此在设计时就能够做到比較灵活,而类适配器就仅仅能通过覆写源角色的方法进行拓展,在实际项目中,对象适配器使用到的场景相对较多。在iOS开发中也推荐多使用组合关系,而尽量降低继承关系,这是一种非常好的编程习惯,因此我在这里仅仅介绍对象适配器,想了解很多其它的关于类适配器的话,请自行Google之。

适配器模式的官方定义:

将一个类的接口变成client所期待的还有一种接口,从而使原本因接口不匹配而无法在一起工作的两个类可以在一起工作。

适配器模式长处

  1. 适配器模式可以让两个没有不论什么关系的类在一起执行,仅仅要适配器这个角色可以搞定他们就成。
  2. 添加?了类的透明性。我们訪问的是目标角色,可是实现却在源角色里。
  3. 提高了类的复用度。源角色在原有系统中还是能够正常使用的。
  4. 灵活性很好。不想要适配器时,删掉这个适配器就好了,其它代码不用改。

适配器模式的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;
}