適配器模式(Adapter Pattern)屬于結(jié)構(gòu)型模式
概述
結(jié)構(gòu)型模式關(guān)注如何將現(xiàn)有的類或?qū)ο蠼M織在一起形成更加強大的結(jié)構(gòu)。
在生活中,我們經(jīng)常遇到這樣的一個問題:輕薄筆記本通常只有 type-c 或者 usb-a 接口,沒有網(wǎng)口。但日常使用中是往往需要連接網(wǎng)口上網(wǎng)的,這時想到的第一個解決方案,就是去買一個轉(zhuǎn)接頭或者擴展塢。它們可以將 type-c 或者 usb-a 轉(zhuǎn)換為其他類型的接口供我們使用,實際上這就是一種適配器模式。
我們常用的充電頭,為什么叫電源適配器呢?傳統(tǒng)的供電是 220V 交流電,但是手機可能只需要 5V 的電壓進行充電,所以雖然現(xiàn)在有電,但是不能直接充。也不可能讓電力公司專門為我們提供一個 5V 的直流電使用,這時電源適配器就開始發(fā)揮作用了。比如蘋果的祖?zhèn)?5V1A 充電頭,實際上就是將 220V 交流電轉(zhuǎn)換為 5V 的直流電進行傳輸。這樣就相當于在 220V 交流電和手機之間,做了一個適配器的角色。
適配器模式分為類適配器和對象適配器。
代碼實現(xiàn)
這里以電腦需要轉(zhuǎn)接器連接網(wǎng)線上網(wǎng)為例:
類適配器
1、定義電腦
/**
* 電腦
* <p>想上網(wǎng),需要插網(wǎng)線
*/
public class Computer {
/**
* 電腦需要連接上轉(zhuǎn)換器才可以上網(wǎng)
*
* @param adapter 轉(zhuǎn)接器
*/
public void connect(NetToUsb adapter) {
// 上網(wǎng)的具體實現(xiàn),找一個轉(zhuǎn)接頭
adapter.connectNetLine();
}
}
2、定義網(wǎng)線
/**
* 網(wǎng)線
*/
public class NetLine {
/**
* 上網(wǎng)
*/
public void online(){
System.out.println("連接網(wǎng)線上網(wǎng)");
}
}
3、定義 usb 轉(zhuǎn)網(wǎng)口轉(zhuǎn)接器
/**
* 轉(zhuǎn)接器
*/
public interface NetToUsb {
/**
* 處理請求,usb -> 網(wǎng)線
*/
void connectNetLine();
}
4、定義類適配器
/**
* 類適配器
*/
public class ClassAdapter extends NetLine implements NetToUsb {
@Override
public void connectNetLine() {
// 可以上網(wǎng)了
super.online();
}
}
5、使用適配器連接網(wǎng)線上網(wǎng)
// 電腦
Computer computer = new Computer();
// 轉(zhuǎn)接器已經(jīng)插上網(wǎng)線
ClassAdapter adapter = new ClassAdapter();
// 電腦連接轉(zhuǎn)接器,成功上網(wǎng)
computer.connect(adapter);
這種實現(xiàn)方式需要占用一個繼承位。如果此時 NetToUsb 不是接口而是抽象類的話,由于 Java 不支持多繼承,就無法實現(xiàn)了。同時根據(jù)合成復用原則,應該更多的通過合成的方式去實現(xiàn)功能。
所以來看看第二種,也是用的比較多的一種模式:對象適配器。
對象適配器
4、定義對象適配器
/**
* 對象適配器
*/
public class ObjectAdapter implements NetToUsb {
/**
* 網(wǎng)線
*/
private NetLine netLine;
public ObjectAdapter(NetLine netLine) {
this.netLine = netLine;
}
@Override
public void connectNetLine() {
// 可以上網(wǎng)了
netLine.online();
}
}
5、使用適配器連接網(wǎng)線上網(wǎng)
/**
* 測試示例
*/
public class ObjectAdapterTest {
@Test
public void test() {
// 電腦
Computer computer = new Computer();
// 網(wǎng)線
NetLine netLine = new NetLine();
// 轉(zhuǎn)接器插上網(wǎng)線
ObjectAdapter adapter = new ObjectAdapter(netLine);
// 電腦連接轉(zhuǎn)接器,成功上網(wǎng)
computer.connect(adapter);
}
}
這樣的方式不會占用繼承位,且滿足合成復用原則,耦合度更低,也更加靈活,推薦使用。
優(yōu)缺點
優(yōu)點
1、可以讓任何兩個沒有關(guān)聯(lián)的類一起運行。
2、提高了類的復用。
3、增加了類的透明度。
4、靈活性好。
缺點
1、過多地使用適配器,會讓系統(tǒng)非常零亂,不易整體進行把握。比如,明明看到調(diào)用的是 A 接口,其實內(nèi)部被適配成了 B 接口的實現(xiàn),一個系統(tǒng)如果太多出現(xiàn)這種情況,無異于一場災難。因此如果不是很有必要,可以不使用適配器,而是直接對系統(tǒng)進行重構(gòu)。
2、由于 Java 至多繼承一個類,所以至多只能適配一個類,而且目標類必須是抽象類。
使用場景
有動機地修改一個正常運行的系統(tǒng)的接口,這時應該考慮使用適配器模式。
注意事項
適配器不是在詳細設(shè)計時添加的,而是解決正在服役的項目的問題。
參考文章來源:http://www.zghlxwxcb.cn/news/detail-668338.html
https://www.bilibili.com/video/BV1mc411h719?p=7&vd_source=299f4bc123b19e7d6f66fefd8f124a03文章來源地址http://www.zghlxwxcb.cn/news/detail-668338.html
到了這里,關(guān)于設(shè)計模式 06 適配器模式的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!