• GOF设计模式——Adapter模式


    一、什么是Adapter模式?

            Adapter模式,又称为适配器模式。

            这是一个很通俗的名字,“适配器”,我们可以联想到笔记本电脑的充电器(专业名称又叫适配器),每一台笔记本电脑会对应只有一个适配器,适配器的作用是对民用的电压和电流进行转换,使得电压和电流满足当前的笔记本电脑的实际需求。那么,到了程序里面,又是怎么理解呢?我们可以将笔记本电脑实际的电压和电流当作是程序的需求,民用电压当作是程序原有情况,那么Adapter模式下的类就是充当这个充电器(适配器)。

    二、Adapter模式的分类:

    1、Class Adapter模式(使用继承)

    所谓的Class Adapter模式就是使用继承的方式实现,就是当Target(需求)是一个接口时,就可以使用继承的方式。

    2、Object Adapter模式(使用委托)

     

     

    Object Adapter模式使用委托的方式,就是将具体实现交给别的对象执行。注意,这里的Tager(需求)已经是一个类,而不是一个接口,由于java只支持单继承的原则,所以对于Adaptee(实际情况),只能通过委托的方式交给Adapter调用。在Adapter类里面多了一个属性adaptee,这是Adaptee类的对象,通过这个对象来调用Adaptee里面的方法。

    三、具体使用

    1、Class Adapter模式

    Main类:充当Client角色,用于使用Print的相关方法(即我要给笔记本电脑充电);

    Print接口:充当Target角色,就是实际需求(即当前笔记本电脑只需要12V直流电压);

    Banner类:充当Adaptee角色,就是实际情况(即当前只有民用220V交流电压);

    PrintBanner类:充当Adapter角色,就是适配器类(即笔记本电脑充电适配器)。

    • Print接口
    public interface Print{
        public abstract void printWerk();//打印削弱
        public abstract void printStrong();//打印增强
    }
    • Banner类
    public class Banner{
        private String string;
        public Banner(String string){
            this.string = string;
        }
     
        public void showWithParen(){
            System.out.println("(" + string + ")");
        }
     
        public void showWithAster(){
            System.out.println("*" + string + "*");
        }
    }
    • PrintBanner类
    public class PrintBanner extends Banner implements Print{
     
        public PrintBanner(String string){
            super(string);
        }
     
        public void printWeak(){
            showWithParen();
        }
     
        public void printStrong(){
            showWithAster();
        }
    }
    • Main类
    public class Main{
        public static void main(String[] args){
            Print p = new PrintBanner("hello world");
            p.printWeak();
            p.printStrong();
        }
    }

    2、Object Adapter模式


    上图的类的角色跟ClassAdapter模式的类的角色一样。

    • Print
    public abstract class Print{
        public abstract void printWeak();
        public abstract void printStrong();
    }
    • PringtManager
    public class PrintBanner extends Print{
        private Banner banner;
     
        public PrintBanner(String string){
            this.banner = new Banner(string);
        }
     
        public void printWeak(){
            banner.showWithParen();
        }
     
        public void printStrong(){
            banner.showWithAster();
        }
    }

     

    Banner类和Main类跟Class Adapter模式的一样,这里不重复。

            定位到main方法,上面两种模式的使用中,在main方法里都没有直接使用到Banner类的方法,也就是我需要给笔记本电脑充电(Print中的两个抽象方法),我根本不关心民用电压多少(Banner类的方法),只要使用这个特制的适配器(PrintBanner类),就可以满足我充电的这个动作需求。

    四、Adapter模式应用场景

            很多时候,我们并不是从零开始编写项目的,即这个项目已经设计了很多个类,或者经常使用已有的其他第三方类,而这些类往往已经被充分测试过,几乎没有bug,并且大量应用到程序的其他地方。如果现在为了适应业务发展,便有了新的需求,那么我们更愿意去通过对已有的类进行进一步的封装,生成新的类,这就是Adapter模式思想。

            通过Adapter模式可以很方便地创建实际所需的方法群,当出现bug时,可以很明确的定位,迅速排除不是现有的类(即Adaptee类)。

            对于软件的版本升级与兼容性,也可以应用Adapter模式。例如,假如现在只想维护新版本,这时可以让新版本扮演Adaptee角色,旧版本扮演Target角色,接着编写一个Adapter角色的类,这样子可以很好的解决新版本与旧版本兼容性的问题,而且只需要维护新版本就可以。

            值得注意的是,当Target与Adaptee的功能完全不同的时候,使用Adapter模式就完全没有意义了。

  • 相关阅读:
    Python保留最后N个元素
    STL算法
    STL迭代器
    STL容器
    C++总结1
    牛客剑指Offer2
    Vue第一天
    UML
    Java继承和组合代码
    Java15后的sealed阻止继承滥用
  • 原文地址:https://www.cnblogs.com/SysoCjs/p/10326776.html
Copyright © 2020-2023  润新知