设计模式之适配器模式

一、什么是适配器模式

适配器模式,将一个类的接口转换为客户端希望的另一个接口,使其原本由于不兼容而不能一起工作的类能一起协同工作。

适配器模式,属于结构型设计模式。

二、适配器模式角色

  • 目标接口:客户端希望的接口类,可以是抽象类或接口类。
  • 适配者类:需要转换为目标接口的被适配类。
  • 适配器类:通过继承或依赖适配者类,把适配者接口转换为目标接口,让客户端直接调用目标接口的方法访问适配者。被适配者对客户端来说是透明的。

三、适配器模式分类

  • 类适配器模式:适配器类,通过继承适配者接口,实现目标接口,完成适配者接口向目标接口的转换。
  • 对象适配器模式:适配器类,通过依赖适配者接口,实现目标接口,完成适配者接口向目标接口的转换。由于类适配器需要继承适配者类,一定程度上耦合度比对象适配器更高,对象适配器更符合“合成复用原则”。
  • 接口适配器模式:当客户端不需要全部实现目标接口提供的方法时,可先定义一个抽象类实现接口,并为该抽象接口的所有方法提供一个默认空实现,这样该抽象类的子类就可以有选择性的重写父类的方法来实现需求。

四、适配器模式UML图

1、类适配器模式

设计模式之适配器模式插图

2、对象适配器模式

设计模式之适配器模式插图2

3、接口适配器模式

设计模式之适配器模式插图4

五、适配器模式demo示例

1、Demo需求

手机想要投影到投影仪上,由于手机是Type-c接口,投影仪是VGA接口。 不能直接投影,需要一个适配器,将视频信号从Type-c口转到VGA口,最后才能输出到大屏幕上。

2、类适配器模式代码实现

/**
  * 适配者类
  *
  * 手机想要投影到投影仪上,由于手机是Type-c接口,投影仪是VGA接口。
  * 不能直接投影,需要一个适配器,将视频信号从Type-c口转到VGA口,最后才能输出到大屏幕上。
  */ public class Phone {

    public void typec(){
        System.out.println("手机输出type-c接口。。。");
    }
 }
/**
  *目标接口
  */ public interface VGA {

     void vgaInterface();
 }
/**
  * 适配器类,将手机号的type-c接口转换为投影仪的VGA接口
  */ public class VGAAdapter extends Phone implements VGA {

     public void vgaInterface() {
         super.typec();
         System.out.println("已得到type-c接口信息");
         System.out.println("已将type-c接口信息转换为vga接口信息....");
     }
 }
/**
  * 客户端测试类
  */ public class Client {

     public static void main(String[] args) {
         VGA vga = new VGAAdapter();
         vga.vgaInterface();
     }
 }

控制台输入日志:

手机输出type-c接口。。。
已得到type-c接口信息
已将type-c接口信息转换为vga接口信息....

3、对象适配器模式代码实现

/**
  * 适配者类
  *
  * 手机想要投影到投影仪上,由于手机是Type-c接口,投影仪是VGA接口。
  * 不能直接投影,需要一个适配器,将视频信号从Type-c口转到VGA口,最后才能输出到大屏幕上。
  */ public class Phone {

    public void typec(){
        System.out.println("手机输出type-c接口。。。");
    }
 }
/**
  *目标接口
  */ public interface VGA {

     void vgaInterface();
 }
/**
  * 对象适配器类
  */ public class VgaObjAdapter implements VGA {

     //依赖适配者类
     private Phone phone;

     // 通过构造方法初始化适配者对象
     public VgaObjAdapter(Phone phone){
         this.phone = phone;
     }

     public void vgaInterface() {
         phone.typec();
         System.out.println("已获取type-c接口数据");
         System.out.println("已通过对象适配器模式,将type-c接口转换为vga接口");
     }
 }
/**
  * 对象适配器客户端测试类
  */ public class Client {

     public static void main(String[] args) {
         VGA vga = new VgaObjAdapter(new Phone());
         vga.vgaInterface();
     }
 }

控制台输入日志:

手机输出type-c接口。。。
已获取type-c接口数据
已通过对象适配器模式,将type-c接口转换为vga接口

4、接口适配器模式代码实现

/**
  * 目标接口类:接口适配器模式
  *
  * 多个方法
  */ public interface Target {

     /**
      * typec适配
      */     void typec();
 
     /**
      * vga适配
      */     void vgaInterface();
 
     /**
      * hdmi适配
      */     void hdmiInterface();
 }
/**
  * 类似适配者类:
  * 定义目标接口抽象类,将目标接口空实现
  */ public abstract class AbstractTarget implements Target {

     public void typec() {
         System.out.println("typec ....");
     }
 
     public void vgaInterface() {
 
     }
 
     public void hdmiInterface() {
 
     }
 }
/**
  * 适配器类,覆写vag适配方法
  */ public class VGAAdapter extends AbstractTarget {

     @Override
     public void vgaInterface() {
         super.typec();
         System.out.println("以获取type-c接口数据");
         System.out.println("已通过接口适配器,将type-c接口转换为vga接口");
     }
 }
/**
  * 客户端测试类
  */ public class Client {

     public static void main(String[] args) {
         VGA vga = new VGAAdapter();
         vga.vgaInterface();
     }
 }

控制台输入日志:

手机输出type-c接口。。。
已得到type-c接口信息
已将type-c接口信息转换为vga接口信息....

发表评论