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模式就完全没有意义了。

原文地址:https://www.cnblogs.com/SysoCjs/p/10326776.html