java 適配器模式(adapter pattern)
什么是適配器模式
是一種結構型的設計模式,它能使接口不兼容的對象能夠相互合作。
這種模式是用來做適配的,它將不兼容的接口轉換為可兼容的接口,讓原本由于讓原本由于接口不兼容而不能一起工作的類可以一起工作。比如現實生活中的例子, USB 轉接頭就充當適配器,把兩種不兼容的接口,通過轉接變得可以一起工作。其別名為包裝器。
主要分為三類:類適配器模式、對象適配器模式、接口適配器模式
原型模式主要包含三個角色:
target目標接口:當前系統業務所期待的接口,它可以是抽象類或者接口。
adaptee適配者類:它是被訪問和適配的現存組件庫中的組件接口。
adapter適配器類:它是一個轉換器,通過繼承或者引用適配者的對象,把適配者接口轉換成目標接口,讓客戶按目標接口的格式訪問適配者。
適配器模式適合應用場景
1.當你希望使用某個類,但是其接口與其他代碼不兼容時,可以使用適配器類
2.如果您需要復用這樣一些類,他們處于同一個繼承體系,并且他們又有了額外的一些共同的方法,這些共同的方法不是所有在這一繼承體系中的子類所具有的共性
3.springMVC中的handlerAdapter,就使用了適配器模式
工作原理
1.適配器模式:將一個類的接口轉換成另一種接口,讓原有接口不兼容的類可以兼容
2.從用戶的角度看不到被適配者,是解耦的
3.用戶調用適配器轉化出來的接口方法,適配器再調用被適配者的相關接口方法
適配器模式的注意事項和細節
1.三種命名方式,是根據src是以怎樣的形式給到adapter(在adapter里的形式)來命名的。
2.類適配器:以類給到,在adapter里,就是將src當作類,繼承
對象適配器:以對象給到,在adapter里,將src作為一個對象,持有
接口適配器:以接口給到,在adapter里,將src作為一個接口,實現
3.adapter最大的作用還是將原本不兼容的接口融合在一起工作。
適配器模式代碼實現
充電器案例:充電器本身相當于adapter,220V交流電相當于src(即被適配者),我們的dst(即目標)5v直流電,手機只有5V時才可以充電。
2.1類適配器
//適配接口(目標接口) public interface IVoltage5V { public int output5V(); } //手機 public class Phone { //充電 public void charging(VoltageAdapter voltageAdapter) { if(voltageAdapter.output5V() == 5) { System.out.println("電壓為5V, 可以充電~~"); } else if (voltageAdapter.output5V() > 5) { System.out.println("電壓大于5V, 不能充電~~"); } } } //被適配的類(充電器) public class Voltage220V { //輸出220V的電壓 public int output220V() { int src = 220; System.out.println("電壓=" + src + "伏"); return src; } } //適配器類:相當于轉換器(將被適配者轉換成目標) public class VoltageAdapter extends Voltage220V implements IVoltage5V { @Override public int output5V() { //獲取到220V電壓 int srcV = output220V(); int dstV = srcV / 44 ; //轉成 5v return dstV; } } //測試 public static void main(String[] args) { System.out.println(" === 類適配器模式 ===="); Phone phone = new Phone(); phone.charging(new VoltageAdapter()); }
運行結果:
類適配器模式注意事項和細節
1.Java是單繼承機制,所以類適配器需要繼承src類這一點算是一個缺點,因為這要求dst必須是接口,有一定局限性。
2.src類的方法在adapter中都會暴露出來,也增加了使用的成本。
3.由于其繼承了src類,所有它可以根據需求重寫src類的方法,使得adapter的靈活性增強了。
2.2對象適配器
//適配接口(目標接口) public interface IVoltage5V { public int output5V(); } //手機 public class Phone { //充電 public void charging(VoltageAdapter voltageAdapter) { if(voltageAdapter.output5V() == 5) { System.out.println("電壓為5V, 可以充電~~"); } else if (voltageAdapter.output5V() > 5) { System.out.println("電壓大于5V, 不能充電~~"); } } } //被適配的類(充電器) public class Voltage220V { //輸出220V的電壓,不變 public int output220V() { int src = 220; System.out.println("電壓=" + src + "伏"); return src; } } //適配器類:相當于轉換器(將被適配者轉換成目標)由于是對象適配器,不是類適配器,所以不繼承被適配的 public class VoltageAdapter implements IVoltage5V { private Voltage220V voltage220V; // 關聯關系-聚合 //通過構造器,傳入一個 Voltage220V 實例 public VoltageAdapter(Voltage220V voltage220v) { this.voltage220V = voltage220v; } @Override public int output5V() { int dst = 0; if(null != voltage220V) { int src = voltage220V.output220V();//獲取220V 電壓 System.out.println("使用對象適配器,進行適配~~"); dst = src / 44; System.out.println("適配完成,輸出的電壓為=" + dst); } return dst; } } //測試 public static void main(String[] args) { // TODO Auto-generated method stub System.out.println(" === 對象適配器模式 ===="); Phone phone = new Phone(); phone.charging(new VoltageAdapter(new Voltage220V())); }
運行結果:
類適配器模式注意事項和細節
1.對象適配器和類適配器其實算是同一種思想,只不過實現方式不同。根據合成復用原則,使用組合替代繼承,所以它解決了類適配器必須繼承src的局限性問題,也不再要求dst必須是接口。
2.使用成本更低,更靈活。
2.3接口適配器
//目標接口 public interface Interface4 { public void m1(); public void m2(); public void m3(); public void m4(); } //在AbsAdapter 我們將 Interface4 的方法進行默認實現 public abstract class AbsAdapter implements Interface4 { //默認實現 public void m1() {} public void m2() {} public void m3() {} public void m4() {} } //測試 public static void main(String[] args) { AbsAdapter absAdapter = new AbsAdapter() { //只需要去覆蓋我們 需要使用 接口方法 @Override public void m1() { System.out.println("使用了m1的方法"); } }; absAdapter.m1(); }
運行結果:
適配器模式優缺點
優點:
1.單一職責原則你可以將接口或數據轉換代碼從程序主要業務邏輯中分離。
2.開閉原則。 只要客戶端代碼通過客戶端接口與適配器進行交互, 你就能在不修改現有客戶端代碼的情況下在程序中添加新類型的適配器。
缺點:
1.代碼整體復雜度增加, 因為你需要新增一系列接口和類。 有時直接更改服務類使其與其他代碼兼容會更簡單。
什么是單一職責原則:
一個類只負責一項職責。若一個類承擔多個職責,當其中某一部分發生變化時,可能會影響其他部分,導致維護困難。
什么是開閉原則:
軟件實體(類、模塊、函數等)應對擴展開放,對修改關閉。在不修改現有代碼的前提下,通過擴展實現新功能。
原文鏈接:https://blog.csdn.net/m0_47944994/article/details/127898298

浙公網安備 33010602011771號