Java設計模式中的適配器模式

基本介紹

  • 適配器模式(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模式最大的作用還是將原本不兼容的接口融合在一起工作。

到此這篇關於Java設計模式中的適配器模式的文章就介紹到這瞭,更多相關Java適配器模式內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: