设计模式-适配器模式

适配器定义:

适配器模式(Adapter Pattern) :将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper)。适配器模式既可以作为类结构型模式,也可以作为对象结构型模式。

角色介绍 

目标(Target)角色:这就是所期待得到的接口。注意:由于这里讨论的是类适配器模式,因此目标不可以是类。

源(Adapee)角色:现在需要适配的接口。

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

分类:

类适配器和对象适配器

类适配器:

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

具体实现:

类适配器模式

/** * Target角色 */
public interface FiveVolt {
    public int getVolt5();
}

/**
* Adaptee角色,需要被转换的对象
*/

public class Volt220 {
    public int getVolt220() {
        return 220;
    }
}

// adapter角色

public class ClassAdapter extends Volt220 implements FiveVolt {

    @Override
    public int getVolt5() {
        return 5;
    }

}

  Target角色给出了需要的目标接口,而Adaptee类则是需要被转换的对象。Adapter则是将Volt220转换成Target的接口。对应的是Target的目标是要获取5V的输出电压,而Adaptee即正常输出电压是220V,此时我们就需要电源适配器类将220V的电压转换为5V电压,解决接口不兼容的问题。

public class Test {
    public static void main(String[] args) {
        ClassAdapter adapter = new ClassAdapter();
        System.out.println("输出电压 : " + adapter.getVolt5());
    }
}

对象适配器:

对象适配器的具体实现

 与类的适配器模式一样,对象的适配器模式把被适配的类的API转换成为目标类的API,与类的适配器模式不同的是,对象的适配器模式不是使用继承关系连接到Adaptee类,而是使用代理关系连接到Adaptee类。

     Adaptee类 ( Volt220 ) 并没有getVolt5()方法,而客户端则期待这个方法。为使客户端能够使用Adaptee类,需要提供一个包装类Adapter。这个包装类包装了一个Adaptee的实例,从而此包装类能够把Adaptee的API与Target类的API衔接起来。Adapter与Adaptee是委派关系,这决定了适配器模式是对象的。

示例代码如下 :

/**
* Target角色
*/

public interface FiveVolt {
    public int getVolt5();
}

/**
* Adaptee角色,需要被转换的对象
*/

public class Volt220 {
    public int getVolt220() {
        return 220;
    }
}

// 对象适配器模式

public class ObjectAdapter implements FiveVolt {

    Volt220 mVolt220;

    public ObjectAdapter(Volt220 adaptee) {
        mVolt220 = adaptee;
    }

    public int getVolt220() {
        return mVolt220.getVolt220();
    }

    @Override
    public int getVolt5() {
        return 5;
    }

}

注意,这里为了节省代码,我们并没有遵循一些面向对象的基本原则。

使用示例 :

public class Test {
    public static void main(String[] args) {
        ObjectAdapter adapter = new ObjectAdapter(new Volt220());
        System.out.println("输出电压 : " + adapter.getVolt5());
    }
}

模式结构:

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

Target:目标抽象类

Adapter:适配器类

Adaptee:适配者类

Client:客户类

适配器模式有对象适配器和类适配器两种实现:

对象适配器:

设计模式-适配器模式_第2张图片
类适配器:

优点:

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

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

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

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

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

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

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

缺点:

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

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

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

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

我的微信二维码如下,欢迎交流讨论

欢迎关注《IT面试题汇总》微信订阅号。每天推送经典面试题和面试心得技巧,都是干货!

微信订阅号二维码如下:

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

参考:
https://github.com/simple-android-framework-exchange/android_design_patterns_analysis/tree/master/adapter/mr.simple
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

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