您的位置:首页 > 其它

十六、适配器模式Adapter(结构型模式)

2016-05-03 14:44 246 查看
1、意图

什么是适配器,大家可能猛一下说不出来,那给大家举个简单的例子,用过港版手机的人都知道,那边的插板是三个大插头,那么回到大陆怎么使用两孔的插座呢,这时候我们就需要转换器了。这个转化器我们也叫作适配器,适配器模式,把一个类的接口变换成客户端所期待的另一种接口,从而使原本不匹配而无法在一起工作的两个,类能够在一起工作。

适配器模式分为类适配器模式和对象适配器模式。
关于类适配器模式,因为java的单继承,如果继承一个类,另外的则只能是接口,需要手动实现相应的方法。

2、结构图和代码



adapted类别的接口提供了SpecificRequest()函数,经由这个转接器转换为Taget类别的新接口,其提供了Request()函数给Client使用。Adapter将Adaptee的接口封装起来,而提供新的接口给Client,这样做的好处是:让Client依赖于新的接口,而不依赖于旧接口,一旦旧接口更改时,并不会影响到Client,因而创造了Adaptee类别的新陈代谢的自由度。

例子:

在我们有A插头是三口的,现在要实现插入两口的电源一起工作,此时我们需要一个中间的适配器,又称转换器来给A电源套上一个两口的插头。

A电源的连接功能

interface PowerA{
public void connect();
}
class PowerAImpl implements PowerA{
public void connect(){
System.out.println("电源A已连接,开始工作");
}
}
B电源的插入功能

interface PowerB{
public void insert();
}
class PowerBImpl implements PowerB{
public void insert(){
System.out.println("电源B已插入,开始工作");
}
}
现在我们可以理解为给A插头添加上一个B插头的插入功能。具体怎么实现呢,写一个适配器类,在其中使用到A的连接方法时添加上B的实现,代码实现如下:

class PowerAdapter implements PowerA{
private PowerB powerB; //被适配的接口
public PowerAdapter(PowerB powerB){
this.powerB = powerB;
}
public void connect(){
powerB.insert();
}
}具体调用如下:
public static void main(String[] args){
PowerA a = new PowerAImpl();
//connect(a);
PowerB b = new PowerBImpl();
PowerAdapter pa = new PowerAdapter(b);
connect(pa);
}
public static void connect(PowerA powerA){
powerA.connect();
}


代码写完了,我们来总结一下,如上:代码中总共有三个角色

    1、源(Adapee)角色:需要适配的接口,也就是A插头

    2、目标(Target)角色:这就是所期待得到的接口,即B插头

    3、适配器(Adaper)角色:适配器类是本模式的核心。适配器把源接口转换成目标接口。显然,这一角色不可以是接口,而必须是具体类。

3、效果

--上面论述的主要是对象适配器,关于类适配器除了实现目标端口外,还要实现你要兼容的源类,这样可以少写几行代码,但是从组合优于继承的角度看,它总则没有那么的干净。
--对同一个适配器(即同一个对象)对同样的源进行双向甚至多向的适配,则能使其适用两个甚至多个客户调用。

适配器模式的优点

    -  更好的复用性

  系统需要使用现有的类,而此类的接口不符合系统的需要。那么通过适配器模式就可以让这些功能得到更好的复用。

    -  更好的扩展性

  在实现适配器功能的时候,可以调用自己开发的功能,从而自然地扩展系统的功能。

适配器模式的缺点

  过多的使用适配器,会让系统非常零乱,不易整体进行把握。比如,明明看到调用的是A接口,其实内部被适配成了B接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。

4、与代理模式的区别
代理模式是接口不变,但里面的内容改变。而适配器模式恰恰相反,接口改变,但内容不变。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: