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

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

故事背景

把奶茶店盘了出去,我和设计模式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

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 成长之路 设计师:Amelia_0503 返回首页