iOS学习笔记(6)——适配器(Adapter)模式

      买过港版iPhone的人都知道,港版iPhone的充电器使用的是英标,与内地的国标标准不通用。因此,如果想在内地使用港版的充电器,就必须再买个转接头,使港版充电器的插头能够与国标插口“适配”。这个转接头的功能即类似于我们这里提到的“适配器”。


      在软件设计中,已有的类与新接口之间不兼容的问题相当常见,同时,我们又不想为新的接口而重写现有的类。此时,就需要用到“适配器模式”。

      定义:将一个类的接口转换为客户希望的另一个接口,它使得原来由于兼容问题不能一起工作的那些类可以一起工作。(《设计模式》,Addison Wesley,1994)。

通常,适配器模式有两种实现方式:类适配器,对象适配器。

1、类适配器

类适配器主要通过继承来适配两个接口,在Objective-C中,多重继承可以通过实现协议,同时又继承基类来实现。要在OC中实现类适配器,首先要有客户端要使用的一套行为的协议,然后要用具体的适配器类来实现该协议,同时适配器类也要继承被适配者。如下图所示。

iOS学习笔记(6)——适配器(Adapter)模式_第1张图片

Adapter是一个Target(目标接口)类型,同时也是一个Adaptee(被适配的类)类型。Adapter重载Target的request方法,但没有重载Adaptee的specificRequest方法,而是在其request方法中调用父类的specificRequest方法(即:[super specificRequest])。当request方法在运行时,向Adaptee发送super消息时,Adaptee按自己的方式执行specificRequest方法。注意:只有当Target是协议而不是类时,类适配器才能用Objective-C实现。

由于类适配器模式采用多继承方式实现,在一定程度上增加了程序的耦合性,而且OC语言本身并不支持多重继承,只能通过实现协议并继承父类来实现。因此,在OC中较常用的还是下一种:对象适配器模式。


2、对象适配器

与类适配器不同的是,对象适配器不继承被适配的类,而是组合了一个对被适配的类的引用,如图所示。

iOS学习笔记(6)——适配器(Adapter)模式_第2张图片

Target和Adapter之间的关系与类适配器相同,而Adapter和Adaptee之间的关系从“属于(继承)”变成了“包含(组合引用)”。这种情况下Adapter持有一个对Adaptee的引用,在request方法中,Adapter发送[adaptee specificRequest]消息,以间接方法Adaptee的specificRequest方法,然后实现客户端请求的其他部分。

示例代码如下:

Target:

@protocol TargetDelegate 
@optional
-(void)request;
@end

@interface Target
@property (weak, nonatomic) id delegate;
@end

@implementation
...

// 通知代理,调用相应的方法
if (_delegate && [_delegate respondsToSelector:@selector(request)]) {  
    [_delegate request];  
}
...
@end

Adapter:

@interface Adapter
{
	Target *_target;
	Adaptee *_adaptee;
}
@end

@implementation Adapter() 

...

// 设置代理
_target.delegate = self;

// 实现代理方法
-(void)request
{
	[_adaptee specificRequest];
}

...

@end
显然,iOS中的委托(Delegate)属于对象适配器。


3、使用适配器模式的情形

①、现有类的接口与需求不匹配;

②、想要复用一个类,该类能够同其他可能带有不兼容接口的类协作;

③、需要适配一个类的几个不同子类,可是让每个子类去子类化一个类适配器又不现实,此时可以使用对象适配器(委托)来适配其父类接口。


你可能感兴趣的:(iOS学习笔记)