Java设计模式7 - 适配器模式

适配器模式

适配器模式说的是,可以把一个类的接口变换成客户端所期待的另一种接口,使得原本因接口不匹配而无法在一起工作的两个类可以一起工作。

 

适配器模式的用途

适配器模式的用途,在网上找了一幅图,挺形象的:

比方说我有一个台灯,其插头是标准的两相的交流电插头,即阳极、阴极。我旅游到了一个地方想用自己的台灯,但发现旅馆里面只有三相的插头,即在阳极、阴极的基础上还多了一个地级。这时候怎么办呢,一个两相到三相的转换器(适配器)就能解决这个问题了,而这正是本模式所做的事情。

 

类适配器

适配器模式分两种,类适配器和对象适配器。先讲类适配器,类适配器把适配的类的API转换成目标类的API,类适配器所涉及的角色有:

1、目标角色

这是所期待得到的接口

2、源角色

现在需要适配的接口

3、适配器角色

模式的核心,适配器把源接口转换成目标接口

 

类适配器示例

目标接口,期待得到sampleOperation1()和sampleOperation2()两个方法:

public interface ClassTarget
{
    /** 这是源类ClassAdaptee也有的方法 */
    public void sampleOperation1();
    
    /** 这是源类ClassAdaptee没有的方法 */
    public void sampleOperation2();
}

源角色,只有一个sampleOperation1()方法:

public class ClassAdaptee
{
    public void sampleOperation1(){}
}

适配器角色扩展了ClassAdaptee,同时又实现了目标接口。由于ClassAdaptee没有提供sampleOperation()2方法,而目标接口又要求这个方法,因此适配器角色实现了这个方法:

public class ClassAdapter extends ClassAdaptee implements ClassTarget
{
    public void sampleOperation2()
    {
        // 相关代码
    }    
}

可能有些人一遍看下来不是很明白,这怎么就是一个适配器模式了,解释一下:

1、客户端期待一个接口ClassTarget有sampleOperation1()和sampleOperation2()这两个方法

2、现在我一个类ClassAdaptee里面只有一个sampleOperation1()方法

3、既然ClassTarget要两个方法,我现在的ClassAdaptee只有一个方法怎么办?搞一个适配器,多变出一个sampleOperation2(),就符合ClassTarget的标准了,由于适配器是ClassTarget接口的实现类,所以可以直接使用适配器作为ClassTarget

 

对象适配器示例

还是一样的,一个目标接口,期待得到sampleOperation1()和sampleOperation2()方法:

public interface ObjectTarget
{
    public void sampleOperation1();
    
    public void sampleOperation2();
}

源角色,只有一个sampleOperation1()方法:

public class ObjectAdaptee
{
    public void sampleOperation1(){}
}

和类适配器不同的是,对象适配器采用了委派关系将源角色与适配器角色关联:

public class ObjectAdapter
{
    private ObjectAdaptee objectAdaptee;
    
    public ObjectAdapter(ObjectAdaptee objectAdaptee)
    {
        this.objectAdaptee = objectAdaptee;
    }
    
    public void sampleOperation1()
    {
        this.objectAdaptee.sampleOperation1();
    }
    
    public void sampleOperation2(){}
}

 

适配器模式在JDK中的应用及解读

写了这么多种设计模式了,可能适配器模式是最不好理解的一种写法。适配器模式的写法很多,写法越多、模式越不好理解,就越应该抓住模式的核心,像适配器模式的核心就是"把一个类的接口变换成客户端所期待的另一种接口"

比方说InputStreamReader吧,创建InputStreamReader对象的时候必须在构造函数中传入一个InputStream实例,然后InputStreamReader的作用就是将InputStream适配到Reader。很显然,适配器就是InputStreamReader,源角色就是InputStream代表的实例对象,目标接口就是Reader类。

OutputStreamWriter也是类似的方式。

 

适配器模式的优缺点

优点

1、有更好的复用性。系统需要使用现有的类,但此类接口不符合系统需要,通过适配器模式让这些功能得到很好的复用

2、有更好的扩展性。实现适配器,可以调用自己开发的功能

缺点

过多使用适配器会使得系统非常凌乱,明明调用的是A接口,内部却被适配成了B接口。因此除非必要,不推荐使用适配器,而是直接对系统重构

posted @ 2020-10-20 10:43  hiram-QI  阅读(115)  评论(0编辑  收藏  举报