今天開始我們就要進入到結構型的設計模式學習之中了,今天講的設計模式是23種設計模式的第六種——適配器模式。通俗的講,適配器的作用就是將兩個互不兼容的東西進行一個適配的操作,它作爲中間的橋樑。 下面我們進入適配器模式的學習。
應用前景:
在現實生活中,適配器這樣的例子隨處可見。就比如用直流電的筆記本電腦接交流電源時需要一個電源適配器,中國人和外國人交流,中間需要一個翻譯等等。
在軟件設計中也可能出現:需要開發的具有某種業務功能的組件在現有的組件庫中已經存在,但它們與當前系統的接口規範不兼容,如果重新開發這些組件成本又很高,這時用適配器模式就能很好地解決這些問題。
適配器模式的概念:
將一個類的接口轉換成客戶希望的另外一個接口,使得原本由於接口不兼容而不能一起工作的那些類能一起工作。
其別名爲包裝器。
特點:
適配器模式的主要優點:
- 客戶端通過適配器可以透明地調用目標接口。
- 複用了現存的類,程序員不需要修改原有代碼而重用現有的適配者類。
- 將目標類和適配者類解耦,解決了目標類和適配者類接口不一致的問題。
其缺點是:
- 對類適配器來說,更換適配器的實現過程比較複雜。
適配器模式工作原理:
- 適配器模式:將一個類的接口轉換成另一種接口,讓原本接口不兼容的類可以兼容。
- 從用戶的角度看不到被適配者,它與目標類是解耦的。
- 用戶調用適配器轉化出來的目標接口方法,適配器再調用被適配者的相關接口方法。
- 用戶收到反饋結果,感覺只是和目標接口交互。
1.類適配器模式
思路分析:
代碼:
適配接口:
package cn.ppdxzz.adapter.classadapter;
/**
* Description:適配接口,輸出5V的電壓
*
* @Date: 2020/3/8 16:22
* @Author: PeiChen
*/
public interface Voltage5V {
//定義一個輸出5V電壓的方法
int output5V();
}
被適配的類:
package cn.ppdxzz.adapter.classadapter;
/**
* Description:被適配的類,正常輸出220V電壓,需要被適配成5V電壓
*
* @Date: 2020/3/8 16:32
* @Author: PeiChen
*/
public abstract class Voltage220V {
//輸出220V的電壓
public int output220V() {
int voltage = 220;
System.out.println("當前電壓:" + voltage + "V");
return voltage;
}
}
充電類:
package cn.ppdxzz.adapter.classadapter;
/**
* Description:充電
*
* @Date: 2020/3/8 16:25
* @Author: PeiChen
*/
public class Phone {
//定義一個給手機充電的方法
public void charging(Voltage5V v) {
if (v.output5V() == 5) {
System.out.println("電壓5V,允許充電");
}else if (v.output5V() > 5){
System.out.println("電壓過高,無法充電");
}else {
System.out.println("電壓異常,禁止充電");
}
}
}
適配器類:
package cn.ppdxzz.adapter.classadapter;
/**
* Description:適配器類,這裏要將220V電壓適配成5V的電壓
*
* @Date: 2020/3/8 16:37
* @Author: PeiChen
*/
public class VoltageAdapter extends Voltage220V implements Voltage5V {
//220V電壓適配成5V電壓
@Override
public int output5V() {
int targetVoltage = 0;
//1.獲取到需被適配的220V電壓
int v = output220V();
//2.返回已適配的5V電壓
targetVoltage = v/44;
System.out.println("適配完成,當前電壓:" + targetVoltage + "V");
return targetVoltage;
}
}
類適配器模式測試:
package cn.ppdxzz.adapter.classadapter;
/**
* Description:類適配器模式
*
* @Date: 2020/3/8 16:44
* @Author: PeiChen
*/
public class Client {
public static void main(String[] args) {
Phone phone = new Phone();
//傳入5V電壓
phone.charging(new VoltageAdapter());
}
}
輸出結果:
當前電壓:220V
適配完成,當前電壓:5V
電壓5V,允許充電
2.對象適配器模式
思路分析:
代碼:
適配接口:
package cn.ppdxzz.adapter.objectadapter;
/**
* Description:適配接口,輸出5V的電壓
*
* @Date: 2020/3/8 17:04
* @Author: PeiChen
*/
public interface Voltage5V {
//定義一個輸出5V電壓的方法
int output5V();
}
被適配的類:
package cn.ppdxzz.adapter.objectadapter;
/**
* Description:被適配的類
*
* @Date: 2020/3/8 17:06
* @Author: PeiChen
*/
public class Voltage220V {
//輸出220V的電壓
public int output220V() {
int voltage = 220;
System.out.println("當前電壓:" + voltage + "V");
return voltage;
}
}
充電類:
package cn.ppdxzz.adapter.objectadapter;
/**
* Description:充電
*
* @Date: 2020/3/8 17:07
* @Author: PeiChen
*/
public class Phone {
//定義一個給手機充電的方法
public void charging(Voltage5V v) {
if (v.output5V() == 5) {
System.out.println("電壓5V,允許充電");
} else if (v.output5V() > 5) {
System.out.println("電壓過高,無法充電");
}else {
System.out.println("電壓異常,禁止充電");
}
}
}
適配器類:
package cn.ppdxzz.adapter.objectadapter;
/**
* Description:適配器類,這裏要將220V電壓適配成5V的電壓
*
* @Date: 2020/3/8 17:09
* @Author: PeiChen
*/
public class VoltageAdapter implements Voltage5V {
private Voltage220V voltage220V;//聚合注入
public VoltageAdapter() {
}
//通過構造器傳入220V電壓
public VoltageAdapter(Voltage220V voltage220V) {
this.voltage220V = voltage220V;
}
@Override
public int output5V() {
int targetVoltage = 0;
if (voltage220V != null) {
//1.獲取到需被適配的220V電壓
int output220V = voltage220V.output220V();//得到需被適配的220V電壓
//2.返回已適配的5V電壓
targetVoltage = output220V/44;
System.out.println("適配完成,當前電壓:" + targetVoltage + "V");
}
return targetVoltage;
}
}
對象適配器模式測試:
package cn.ppdxzz.adapter.objectadapter;
/**
* Description:對象適配器模式
*
* @Date: 2020/3/8 17:22
* @Author: PeiChen
*/
public class Client {
public static void main(String[] args) {
Phone phone = new Phone();
phone.charging(new VoltageAdapter(new Voltage220V()));
}
}
輸出結果:
當前電壓:220V
適配完成,當前電壓:5V
電壓5V,允許充電
3.接口適配器模式
思路分析:
代碼:
適配接口:
package cn.ppdxzz.adapter.interfaceadapter;
/**
* Description:適配接口
*
* @Date: 2020/3/8 17:36
* @Author: PeiChen
*/
public interface InterfaceTest {
//定義三個測試方法
void test1();
void test2();
void test3();
}
適配器抽象類:
package cn.ppdxzz.adapter.interfaceadapter;
/**
* Description:AbstractAdapter抽象類,默認實現接口的所有方法
*
* @Date: 2020/3/8 17:40
* @Author: PeiChen
*/
public abstract class AbstractAdapter implements InterfaceTest {
@Override
public void test1() {
}
@Override
public void test2() {
}
@Override
public void test3() {
}
}
接口適配器模式測試:
package cn.ppdxzz.adapter.interfaceadapter;
/**
* Description:接口適配器模式
*
* @Date: 2020/3/8 17:42
* @Author: PeiChen
*/
public class Client {
public static void main(String[] args) {
//匿名內部類
AbstractAdapter adapter = new AbstractAdapter() {
@Override
public void test1() {
super.test1();
System.out.println("測試test1方法");
}
};
adapter.test1();
}
}
輸出結果:
測試test1方法
適配器模式源碼分析:
SpringMVC中的HandlerAdapter就使用到了適配器模式。
總結:
適配器模式最大的作用還是將原本不兼容的接口融合在一起工作。
適配器模式到這裏就講解完畢了,後續會繼續更新剩下的設計模式,敬請期待。
super.test1();
System.out.println("測試test1方法");
}
};
adapter.test1();
}
}
輸出結果:
```markdown
測試test1方法
適配器模式源碼分析:
SpringMVC中的HandlerAdapter就使用到了適配器模式。
[外鏈圖片轉存中…(img-ucQeFOeC-1587272709049)]
總結:
適配器模式最大的作用還是將原本不兼容的接口融合在一起工作。
適配器模式到這裏就講解完畢了,後續會繼續更新剩下的設計模式,敬請期待。
微信公衆號,JavaAnything,期待你的關注!