Java設(shè)計(jì)模式中的適配器模式
基本介紹
- 適配器模式(Adapter Pattern)將某個(gè)類的接口轉(zhuǎn)換成客戶端期望的另一個(gè)接口表示,主的目的是兼容性,讓原本因接口不匹配不能一起工作的兩個(gè)類可以協(xié)同工作。其別名為包裝器(Wrapper)
- 適配器模式屬于結(jié)構(gòu)型模式
- 主要分為三類:類適配器模式、對(duì)象適配器模式、接口適配器模式
工作原理
- 適配器模式:將一個(gè)類的接口轉(zhuǎn)換成另一種接口.讓原本接口不兼容的類可以兼容。
- 從用戶 的角度看不到被適配者,是解耦的。
- 用戶 調(diào)用適配器轉(zhuǎn)化出來的目標(biāo)接口方法,適配器再調(diào)用被適配者的相關(guān)接口方法。
- 用戶收到反饋結(jié)果, 感覺只是和目標(biāo)接口交互。
類適配器模式
背景介紹:在中國(guó)電源大都是220伏的,而日常生活中手機(jī)的充電確是5伏1安(蘋果),通過類適配器模擬電源適配器實(shí)現(xiàn)手機(jī)充電功能

Voltage220V(被適配電源)
public class Voltage220V {
public int output220V() {
int src = 220;
System.out.println("電壓 = " + src + "伏");
return src;
}
}Voltage5V(目標(biāo)輸出)
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(手機(jī)充電)
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());
}
}實(shí)現(xiàn)結(jié)果:

類適配器模式注意事項(xiàng)和細(xì)節(jié)
- Java是單繼承機(jī)制,所以類適配器需要繼承src類這一點(diǎn)算是- -一個(gè)缺點(diǎn),因?yàn)檫@要求dst必須是接口,有一定局限性;
- src類的方法在Adapter中都會(huì)暴露出來,也增加了使用的成本。
對(duì)象適配器模式
優(yōu)點(diǎn):
- 基本思路和類的適配器模式相同,只是將Adapter類作修改,不是繼承src類,而是持有src類的實(shí)例,以解決兼容性的問題。即: 持有sre類,實(shí)現(xiàn)dst類接口,完成src->dst的適配
- 根據(jù)“合成復(fù)用原則”,在系統(tǒng)中盡量使用關(guān)聯(lián)關(guān)系(聚合)來替代繼承關(guān)系。
- 對(duì)象適配器模式是適配器模式常用的一種
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(測(cè)試)
public class Client {
public static void main(String[] args) {
System.out.println("====對(duì)象適配器模式====");
Phone phone = new Phone();
phone.charging(new VoltageAdapter(new Voltage220V()));
System.out.println("--------------------");
phone.charging(new VoltageAdapter(null));
}
}實(shí)現(xiàn)結(jié)果:

接口適配器模式
簡(jiǎn)介:
- 一些書籍稱為:適配器模式(Default Adapter Pattermn)或缺省適配器模式。
- 核心思路:當(dāng)不需要全部實(shí)現(xiàn)接口提供的方法時(shí),可先設(shè)計(jì)一個(gè)抽象類實(shí)現(xiàn)接口,并為該接口中每個(gè)方法提供一個(gè)默認(rèn)實(shí)現(xiàn)(空方法),那么該抽象類的子類可有選擇地覆蓋父類的某些方法來實(shí)現(xiàn)需求。
- 適用于一個(gè)接口不想使用其所有的方法的情況。
UML類圖
背景介紹:模擬springMVC源碼展示接口設(shè)計(jì)模式

接口適配器和實(shí)現(xiàn)類
///定義一個(gè)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實(shí)現(xiàn)
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) {
// 得到對(duì)應(yīng)適配器
HandlerAdapter adapter = getHandler(controller);
// 通過適配器執(zhí)行對(duì)應(yīng)的controller對(duì)應(yīng)方法
if (adapter != null) {
adapter.handle(controller);
} else {
System.out.println("沒有該適配器...");
}
}
public HandlerAdapter getHandler(Controller controller) {
//遍歷:根據(jù)得到的controller(handler), 返回對(duì)應(yīng)適配器
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());
}
}
實(shí)現(xiàn)結(jié)果:

適配器模式的注意事項(xiàng)和細(xì)節(jié)
- 三種命名方式,是根據(jù)sre 是以怎樣的形式給到Adapter (在Adapter里的形式)來命名的。
- 類適配器:以類給到,在Adapter里,就是將src當(dāng)做類,繼承
- 對(duì)象適配器:以對(duì)象給到,在Adapter里,將sre作為一個(gè)對(duì)象,持有
- 接口適配器:以接口給到,在Adapter里,將src作為一個(gè)接口,實(shí)現(xiàn)Adapter模式最大的作用還是將原本不兼容的接口融合在一起工作。
到此這篇關(guān)于Java設(shè)計(jì)模式中的適配器模式的文章就介紹到這了,更多相關(guān)Java適配器模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring用代碼來讀取properties文件實(shí)例解析
這篇文章主要介紹了Spring用代碼來讀取properties文件實(shí)例解析,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-01-01
Java選擇結(jié)構(gòu)與循環(huán)結(jié)構(gòu)的使用詳解
循環(huán)結(jié)構(gòu)是指在程序中需要反復(fù)執(zhí)行某個(gè)功能而設(shè)置的一種程序結(jié)構(gòu)。它由循環(huán)體中的條件,判斷繼續(xù)執(zhí)行某個(gè)功能還是退出循環(huán),選擇結(jié)構(gòu)用于判斷給定的條件,根據(jù)判斷的結(jié)果判斷某些條件,根據(jù)判斷的結(jié)果來控制程序的流程2022-03-03
IDEA調(diào)試技巧條件斷點(diǎn)實(shí)現(xiàn)步驟詳解
這篇文章主要介紹了IDEA調(diào)試技巧條件斷點(diǎn)實(shí)現(xiàn)步驟詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09
初探Spring Cloud Gateway實(shí)戰(zhàn)
這篇文章主要介紹了創(chuàng)建網(wǎng)關(guān)項(xiàng)目(Spring Cloud Gateway)過程詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2021-08-08

