设计模式——适配器模式

Posted 爱学习的大鱼

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式——适配器模式相关的知识,希望对你有一定的参考价值。

基本介绍

  • 适配器模式(Adapter Pattern)将某个类的接口转换成客户端期望的另一个接口表示,主的目的是兼容性,让原本因接口不匹配不能一起工作的两个类可以协同工作。其别名为包装器(Wrapper)
  • 适配器模式属于结构型模式
  • 主要分为三类:类适配器模式、对象适配器模式、接口适配器模式

工作原理

  • 适配器模式:将一个类的接口转换成另一种接口.让原本接口不兼容的类可以兼容。
  • 从用户 的角度看不到被适配者,是解耦的。
  • 用户 调用适配器转化出来的目标接口方法,适配器再调用被适配者的相关接口方法。
  • 用户收到反馈结果, 感觉只是和目标接口交互。

类适配器模式

背景介绍:在中国电源大都是220伏的,而日常生活中手机的充电确是5伏1安(苹果),通过类适配器模拟电源适配器实现手机充电功能

Voltage220V(被适配电源)

public class Voltage220V 

    public int output220V() 
        int src = 220;
        System.out.println("电压 = " + src + "伏");
        return src;
    

Voltage5V(目标输出)

public interface Voltage5V 
    int output5V();

VoltageAdapter(电源适配器)

public class VoltageAdapter extends Voltage220V implements Voltage5V 

    @Override
    public int output5V() 
        int src = output220V();
        int dst = src / 44;
        System.out.printf("适配器将%d伏====>%d伏\\n", src, dst);
        return dst;
    

Phone(手机充电)

public class Phone 

    public void charging(Voltage5V v) 
        int src = v.output5V();
        if (src <= 5 && src > 0) 
            System.out.println("电压 = " + src + "伏,可以充电...");
         else if (src > 5) 
            System.out.println("电压过高");
         else 
            System.out.println("没有充电...");
        
    

Client

public class Client 
    public static void main(String[] args) 

        System.out.println("====类适配器模式====");
        Phone phone = new Phone();
        phone.charging(new VoltageAdapter());
    

实现结果:

类适配器模式注意事项和细节

  • Java是单继承机制,所以类适配器需要继承src类这一点算是- -一个缺点,因为这要求dst必须是接口,有一定局限性;
  • src类的方法在Adapter中都会暴露出来,也增加了使用的成本。

对象适配器模式

优点:

  • 基本思路和类的适配器模式相同,只是将Adapter类作修改,不是继承src类,而是持有src类的实例,以解决兼容性的问题。即: 持有sre类,实现dst类接口,完成src->dst的适配
  • 根据“合成复用原则”,在系统中尽量使用关联关系(聚合)来替代继承关系。
  • 对象适配器模式是适配器模式常用的一种

UML类图:

其他代码与上一致,修改电源适配器即可:

public class VoltageAdapter implements Voltage5V 
    private Voltage220V voltage220V = null;

    public VoltageAdapter(Voltage220V voltage220V) 
        this.voltage220V = voltage220V;
    

    @Override
    public int output5V() 
        int src = 0;
        if (voltage220V != null) 
            src = voltage220V.output220V();
        
        int dst = src / 44;
        System.out.printf("适配器将%d伏====>%d伏\\n",src,dst);
        return dst;
    

Client(测试)

public class Client 
    public static void main(String[] args) 
        System.out.println("====对象适配器模式====");
        Phone phone = new Phone();
        phone.charging(new VoltageAdapter(new Voltage220V()));
        System.out.println("--------------------");
        phone.charging(new VoltageAdapter(null));
    

实现结果:

接口适配器模式

简介:

  • 一些书籍称为:适配器模式(Default Adapter Pattermn)或缺省适配器模式。
  • 核心思路:当不需要全部实现接口提供的方法时,可先设计一个抽象类实现接口,并为该接口中每个方法提供一个默认实现(空方法),那么该抽象类的子类可有选择地覆盖父类的某些方法来实现需求。
  • 适用于一个接口不想使用其所有的方法的情况。

UML类图

背景介绍:模拟springMVC源码展示接口设计模式

接口适配器和实现类

///定义一个Adapter接口 
public interface HandlerAdapter 
   public boolean support(Controller handler);

   public void handle(Controller handler);


// 多种适配器类
class SimpleHandlerAdapter implements HandlerAdapter 

   public void handle(Controller handler) 
       handler.doHandler();
   

   public boolean support(Controller handler) 
      return (handler instanceof SimpleController);
   



class HttpHandlerAdapter implements HandlerAdapter 

   public void handle(Controller handler) 
      handler.doHandler();
   

   public boolean support(Controller handler) 
      return (handler instanceof HttpController);
   



class AnnotationHandlerAdapter implements HandlerAdapter 

   public void handle(Controller handler) 
      handler.doHandler();
   

   public boolean support(Controller handler) 

      return (handler instanceof AnnotationController);
   

模拟Controller

//多种Controller实现  
public interface Controller 
   void doHandler();


class HttpController implements Controller 
   @Override
   public void doHandler() 
      System.out.println("http...");
   


class SimpleController implements Controller 
   @Override
   public void doHandler() 
      System.out.println("simple...");
   


class AnnotationController implements Controller 
   @Override
   public void doHandler() 
      System.out.println("annotation...");
   

模拟DispatchServlet

public class DispatchServlet 

   public static List<HandlerAdapter> handlerAdapters = new ArrayList<HandlerAdapter>();

   public DispatchServlet() 
      handlerAdapters.add(new AnnotationHandlerAdapter());
      handlerAdapters.add(new HttpHandlerAdapter());
      handlerAdapters.add(new SimpleHandlerAdapter());
   

   public void doDispatch(Controller controller) 
      // 得到对应适配器
      HandlerAdapter adapter = getHandler(controller);
      // 通过适配器执行对应的controller对应方法
      if (adapter != null) 
         adapter.handle(controller);
       else 
         System.out.println("没有该适配器...");
      

   

   public HandlerAdapter getHandler(Controller controller) 
      //遍历:根据得到的controller(handler), 返回对应适配器
      for (HandlerAdapter adapter : this.handlerAdapters) 
         if (adapter.support(controller)) 
            return adapter;
         
      
      return null;
   

   public static void main(String[] args) 
      new DispatchServlet().doDispatch(new SimpleController() ); 
        new DispatchServlet().doDispatch(new HttpController() ); 
        new DispatchServlet().doDispatch(new AnnotationController()); 
   

实现结果:

适配器模式的注意事项和细节

  • 三种命名方式,是根据sre 是以怎样的形式给到Adapter (在Adapter里的形式)来命名的。
  • 类适配器:以类给到,在Adapter里,就是将src当做类,继承
  • 对象适配器:以对象给到,在Adapter里,将sre作为一个对象,持有
  • 接口适配器:以接口给到,在Adapter里,将src作为一个接口,实现Adapter模式最大的作用还是将原本不兼容的接口融合在一起工作。

以上是关于设计模式——适配器模式的主要内容,如果未能解决你的问题,请参考以下文章

适配器模式

架构师内功心法,中国与日本交流电压兼容性问题的适配器模式详解

架构师内功心法,中国与日本交流电压兼容性问题的适配器模式详解

面向对象编程思想-适配器模式

设计模式之适配器模式

适配器模式