十二、适配器模式——解决充电的烦恼 #和设计模式一起旅行#

轻轻的我走了,
正如我轻轻的来;
我轻轻的招手,
作别西天的云彩。
——徐志摩 《再别康桥》

故事背景

把奶茶店盘了出去,我和设计模式MM,继续上路,坐着冒着烟的飞机来到了剑桥,这里真是个美丽的地方,我用手机拍了很多的照片手机没电了,也玩的累了。

找了个酒店 ,准备休息一下,然后给我的手机充充电。 才知道英国的插座都是下面这个样子:

插座

而我的手机充电器是这个样子的:

手机充电器

那这就比较尴尬了,我并不能改变电源的插座,也不能改变我手机的充电器,因此我需要一个转换器,或者说是一个适配器。适配器大概是这个样子,大概是这样的,画的不好,哈哈:

适配器

设计模式MM看到此种场景,就告诉我,这种情况和 一种叫做 适配器模式的武功很相似。让我去学习学习!

背景纯属yy!为了引出本篇的主题。

故事主角

在上面的背景描述中,我们知道不能改变电源的插座,也不能改变手机的充电器,也就是手机的充电器不认识这个插座的(不能兼容这个插座)。类比在代码的世界中,就是有一个完整的系统A,我们需要使用系统A中某个类的功能(方法),但是我们的客户端不认识这个系统A中这个类,只认识另外要给不相关的接口。

注:系统A中的这个类和客户端代码都是一套完整的结构,不能修改!(这个和插座和手机充电器一样,都是完整的,不能修改!)

适配器模式(Adapter Pattern):将类的一个接口,转换成为客户期望的另一个接口,适配器让原本接口不兼容的类可以合作无间。

适配器模式从实现方式上分为两种,对象适配器(组合)和类适配器(继承)。在对象适配器模式中,适配器与适配者之间是关联关系;在类适配器模式中,适配器与适配者之间是继承(或实现)关系。

下面实际开发中,对象适配器使用频率更高,对象适配器模式结构图:

对象适配器结构图

  • Target(目标抽象类):定义客户所需接口。可是一个抽象类或者接口。
  • Adapter(适配器类):是配送可以调用另一个接口,作为转换器,是适配器中的核心。
  • Adaptee(适配者类):适配者也就是被适配器的对象。

简单代码表示:

class Adapter implements Target{
    private Adaptee adaptee;//适配者对象的引用

    public Adapter(Adaptee adaptee){
        this.adaptee = adaptee;
    }

    public void request(){
        adaptee.specificRequest();//调用适配器方法
    }
}


武功修炼

通过对上面的适配器的简单学习后,我们实现手机充电的难题。

第一种适配器不需要做什么工作,只需要适配两个类即可。就像一根粗的水管和一根细的水管要接在一起,那么需要一个适配的转接水管,这个转接的水管内部不进行任何处理,只是一个适配作用。

//酒店插座
public class HotelSocket {

    public void socket(){
        System.out.println("四个头插座充电");
    }
}
//抽象的目标接口类
public interface Socket {

    void socket();
}

public class SockterAdapter implements Socket{

    private HotelSocket socket;

    public SockterAdapter(HotelSocket socket){
        this.socket = socket;
    }

    @Override
    public void socket() {
        System.out.println("适配器转换.......");
        socket.socket();
    }
}


public class Phone {

    private Socket adapter;

    public Phone(Socket adapter){
        this.adapter = adapter;
    }

    //手机充电
    public void charger(){
        System.out.println("手机充电....");
        adapter.socket();
    }
}


public class Test {
    public static void main(String[] args) {
        HotelSocket hotelSocket = new HotelSocket();

        Socket socket = new SockterAdapter(hotelSocket);

        Phone phone = new Phone(socket);

        phone.charger();

    }
}

第二种适配器因为四头的插座电压为250V,而手机需要的充电电压是5V,所以适配器需要将电压进行转换。


//酒店插座
public class HotelSocket {

    public int socket(){

        return 250;
    }
}

//抽象的目标接口类
public interface Socket {

    int socket();
}


public class SockterAdapter implements Socket{

    private HotelSocket socket;

    public SockterAdapter(HotelSocket socket){
        this.socket = socket;
    }

    @Override
    public int socket() {

        int soucre =  socket.socket();
        //适配器进行处理,内部做了一些工作
        return soucre / 50;
    }
}

public class Phone {

    private Socket adapter;

    public Phone(Socket adapter){
        this.adapter = adapter;
    }

    //手机充电
    public void charger(){
        int v = adapter.socket();
        if(v == 5){//只有是5v的才能充电
            System.out.println("电压符合标准,充电中.....");
        }else{
            System.out.println("不能充电");
        }
    }
}

public class Test {
    public static void main(String[] args) {
        HotelSocket hotelSocket = new HotelSocket();

        Socket socket = new SockterAdapter(hotelSocket);

        Phone phone = new Phone(socket);

        phone.charger();

    }
}

Spring中的设计模式-适配器模式

总结

优点
- 引入一个适配器类,重用现有的适配者,无须修改原有结构。(如手机充电器例子,引入适配器则不需要修改插座和手机充电器)。
- 增加了类的透明性和复用性。(如手机充电器例子,手机不用知道插座输入的电压到底是多少,插座输入的电压对于手机充电器是透明的,并且这个适配器不仅能适配我的手机,以后其他的和我手机一样的充电器也可以用,则就具有复用性。)
- 灵活性比较好。(如果我从英国去了日本,我也只需要更换适配器即可,不需要对我的手机充电器做修改,也不需要对日本的插座做修改)

缺点
- 在java中类适配器只能适配一个类,因为java不支持多重继承。
- 对象适配器要更换被适配者比较麻烦,需要适配器中的所有适配的方法进行修改。

适用场景

  • 如果两个接口不兼容情况,并且这两个接口都不能进行修改,结构已经固定了。要使整个两者之间可以合作。

  • 系统需要使用一些现有的类,而这些类的接口(如方法名)不符合系统的需要,甚至没有这些类的源代码。

  • 想创建一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。

注:适配器模式是补救措施,所以在系统设计过程中请忘掉这个设计模式,这个模式只是在你无可奈何时的补救方式

Next 期待下一篇吧!讲讲外观模式!

参考


如果您觉得这篇博文对你有帮助,请点赞或者喜欢,让更多的人看到,谢谢!

如果帅气(美丽)、睿智(聪颖),和我一样简单善良的你看到本篇博文中存在问题,请指出,我虚心接受你让我成长的批评,谢谢阅读!
祝你今天开心愉快!


欢迎访问我的csdn博客,我们一同成长!

不管做什么,只要坚持下去就会看到不一样!在路上,不卑不亢!

博客首页 : http://blog.csdn.net/u010648555

猜你喜欢

转载自blog.csdn.net/u010648555/article/details/80865391