设计模式—适配器模式

本文博客同步发表在 http://hjxandhmr.github.io/2016/06/02/DesignPattern-Adapter/
今天我们来学习一种结构型模式,适配器模式(Adapter Pattern)。

模式定义

将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper)。适配器模式有两种,一种是对象适配器,一种是类适配器。

模式结构

适配器模式包含如下角色:

Target: 目标抽象类
Adapter: 适配器类
Adaptee: 适配者类
Client: 客户类

UML图

类适配器UML图

设计模式—适配器模式_第1张图片

对象适配器UML图

设计模式—适配器模式_第2张图片

类适配器模式代码实现

Target.java

public interface Target {

    void sampleOperation1();

    void sampleOperation2();
}

Adaptee.java

public class Adaptee {

    public void sampleOperation1() {
        System.out.println("sampleOperation1");
    }
}

Adapter.java


public class Adapter extends Adaptee implements Target {

    @Override
    public void sampleOperation2() {
        System.out.println("sampleOperation2");
    }

}

测试类


public class MyClass {

    public static void main(String[] args) {
        Adapter adapter = new Adapter();
        adapter.sampleOperation1();
        adapter.sampleOperation2();
    }
}

运行结果

设计模式—适配器模式_第3张图片

对象适配器代码实现

Target.java


public interface Target {

    void sampleOperation1();

    void sampleOperation2();
}

Adaptee.java

public class Adaptee {

    public void sampleOperation1() {
        System.out.println("sampleOperation1");
    }
}

Adapter.java


public class Adapter implements Target {

    private Adaptee mAdaptee;

    public Adapter(Adaptee adaptee) {
        mAdaptee = adaptee;
    }

    @Override
    public void sampleOperation1() {
        mAdaptee.sampleOperation1();
    }

    @Override
    public void sampleOperation2() {
        System.out.println("sampleOperation2");
    }

}

测试类


public class MyClass {

    public static void main(String[] args) {
        Adapter adapter =new Adapter(new Adaptee());
        adapter.sampleOperation1();
        adapter.sampleOperation2();
    }
}

运行结果

设计模式—适配器模式_第4张图片

模式分析

  • 类适配器使用对象继承的方式,是静态的定义方式;而对象适配器使用对象组合的方式,是动态组合的方式。

  • 对于类适配器,由于适配器直接继承了Adaptee,使得适配器不能和Adaptee的子类一起工作,因为继承是静态的关系,当适配器继承了Adaptee后,就不可能再去处理 Adaptee的子类了。

  • 对于对象适配器,一个适配器可以把多种不同的源适配到同一个目标。换言之,同一个适配器可以把源类和它的子类都适配到目标接口。因为对象适配器采用的是对象组合的关系,只要对象类型正确,是不是子类都无所谓。

  • 对于类适配器,适配器可以重定义Adaptee的部分行为,相当于子类覆盖父类的部分实现方法。

  • 对于对象适配器,要重定义Adaptee的行为比较困难,这种情况下,需要定义Adaptee的子类来实现重定义,然后让适配器组合子类。虽然重定义Adaptee的行为比较困难,但是想要增加一些新的行为则方便的很,而且新增加的行为可同时适用于所有的源。

  • 对于类适配器,仅仅引入了一个对象,并不需要额外的引用来间接得到Adaptee。

  • 对于对象适配器,需要额外的引用来间接得到Adaptee。

  • 建议尽量使用对象适配器的实现方式,多用合成/聚合、少用继承。当然,具体问题具体分析,根据需要来选用实现方式,最适合的才是最好的。

适配器模式的优点

  • 将目标类和适配者类解耦,通过引入一个适配器类来重用现有的适配者类,而无须修改原有代码。

  • 增加了类的透明性和复用性,将具体的实现封装在适配者类中,对于客户端类来说是透明的,而且提高了适配者的复用性。

  • 灵活性和扩展性都非常好,通过使用配置文件,可以很方便地更换适配器,也可以在不修改原有代码的基础上增加新的适配器类,完全符合“开闭原则”。

类适配器模式还具有如下优点:

  • 由于适配器类是适配者类的子类,因此可以在适配器类中置换一些适配者的方法,使得适配器的灵活性更强。

对象适配器模式还具有如下优点:

  • 一个对象适配器可以把多个不同的适配者适配到同一个目标,也就是说,同一个适配器可以把适配者类和它的子类都适配到目标接口。

适配器模式的缺点

类适配器模式的缺点如下:

  • 对于Java、C#等不支持多重继承的语言,一次最多只能适配一个适配者类,而且目标抽象类只能为抽象类,不能为具体类,其使用有一定的局限性,不能将一个适配者类和它的子类都适配到目标接口。

对象适配器模式的缺点如下:

  • 与类适配器模式相比,要想置换适配者类的方法就不容易。如果一定要置换掉适配者类的一个或多个方法,就只好先做一个适配者类的子类,将适配者类的方法置换掉,然后再把适配者类的子类当做真正的适配者进行适配,实现过程较为复杂。

参考
http://design-patterns.readthedocs.io/zh_CN/latest/structural_patterns/adapter.html
http://www.cnblogs.com/java-my-life/archive/2012/04/13/2442795.html

欢迎大家关注我的微信公众号,我会不定期的分享些Android开发的技巧

[站外图片上传中……(5)]

你可能感兴趣的:(设计模式—适配器模式)