一、類適配器模式介紹
基本介紹
1)適配器模式(Adapter Pattern)將某個類的接口轉換成客戶端期望的另一個接口表示,主的目的是兼容性,讓原本接口不匹配不能一起工作的兩個類可以協同工作。其別名爲包裝器(Wrapper)。
2)適配器模式屬於結構型模式。
3)主要分爲三類:類適配器模式、對象適配器模式、接口適配器模式。
工作原理
1)適配器模式:將一個類的接口轉換成另一種接口,讓原本接口不兼容的類可以兼容;
2)從用戶的角度看不到被適配者,是解耦的;
3)用戶調用適配器轉化出來的目標接口方法,適配器再調用被適配者的相關接口方法;
4)用戶收到反饋結果,感覺只是和目標接口交互。
類適配器模式注意事項和細節
1)Java是單繼承機制,所以類適配器需要繼承src類這一點算是一個缺點,因爲這要求dst必須是接口,有一定侷限性;
2)src類的方法在Adapter中會暴露出來,也增加了使用的成本;
3)由於其繼承了src類,所以它可以根據需求重寫src類的方法,使得Adapter的靈活性增強了。
二、類適配器模式應用
- 以生活中充電器的例子來講解適配器,充電器本身相當於Adapter,220V交流電相當於src(被適配者),dst(即目標)是5V直流電。
- 類圖
- 代碼
1)被適配者類
public class Voltage220V {
//輸出220V的電壓
public int output220V(){
int src = 220;
System.out.println("電壓="+ src + "伏");
return src;
}
}
2)適配接口類
public interface IVoltage5V {
public int output5V();
}
3)適配器類
//適配器類
public class VoltageAdapter extends Voltage220V implements IVoltage5V {
public int output5V() {
//獲取到220V電壓
int srcV = output220V();
int dstV = srcV/44;//轉成5V
return dstV;
}
}
4)目標類
public class Phone {
//充電
public void charging(IVoltage5V iVoltage5V){
if(iVoltage5V.output5V() == 5){
System.out.println("電壓爲5V,可以充電~");
}else if(iVoltage5V.output5V() > 5){
System.out.println("電壓大於5V,不能充電~");
}
}
}
5)客戶端
public class Client {
public static void main(String[] args) {
System.out.println("==== 類適配器模式 ====");
Phone phone = new Phone();
phone.charging(new VoltageAdapter());
}
}
三、對象適配器模式
對象適配器模式介紹
1)基本思路和類的適配器模式相同,只是將Adapter類做修改,不是繼承src類,而是持有src類的實例,以解決兼容性的問題。即:持有src類(被適配的類),實現dst類(目標類)接口,完成src->dst的適配;
2)根據“合成複用原則”,在系統中儘量使用關聯關係來替代繼承關係;
3)對象適配器模式是適配器模式常用的一種。
對象適配器模式注意事項和細節
1)對象適配器和類適配器其實算是同一種思想,只不過實現方式不同。根據合成複用原則,使用組合替代繼承,所以它解決了類適配器必須繼承src的侷限性問題,也不再要求dst必須是接口。
2)使用成本更低,更靈活。
四、對象適配器模式應用實例
- 應用實例說明
以生活中充電器的例子來講解適配器,充電器本身相當於Adapter,220V交流電相當於src(被適配者),我們的目的dst(即目標)是5V直流電,使用對象適配器模式完成。 - 類圖
- 代碼
1)被適配者類
public class Voltage220V {
//輸出220V的電壓
public int output220V(){
int src = 220;
System.out.println("電壓="+ src + "伏");
return src;
}
}
2)適配接口類
public interface IVoltage5V {
public int output5V();
}
3)適配器類
//適配器類
public class VoltageAdapter implements IVoltage5V {
private Voltage220V voltage220V;//關聯關係-聚合
//通過構造器,傳入一個Voltage220V 實例
public VoltageAdapter(Voltage220V voltage220V) {
this.voltage220V = voltage220V;
}
public int output5V() {
int dst = 0;
if(voltage220V != null){
int src = voltage220V.output220V();//獲取220V 電壓
System.out.println("使用對象適配器,進行適配~~");
dst = src/44;
System.out.println("適配完成,輸出的電壓爲="+dst);
}
return dst;
}
}
4)目標類
public class Phone {
//充電
public void charging(IVoltage5V iVoltage5V){
if(iVoltage5V.output5V() == 5){
System.out.println("電壓爲5V,可以充電~");
}else if(iVoltage5V.output5V() > 5){
System.out.println("電壓大於5V,不能充電~");
}
}
}
5)客戶端
public class Client {
public static void main(String[] args) {
System.out.println("==== 類適配器模式 ====");
Phone phone = new Phone();
phone.charging(new VoltageAdapter(new Voltage220V()));
}
}
五、接口適配器模式
接口適配器模式介紹
1)一些書籍稱爲:適配器模式(Default Adapter Pattern)或缺省適配器模式。
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 class Client {
public static void main(String[] args) {
AbsAdapter absAdapter = new AbsAdapter() {
//只需要去覆蓋我們需要使用的接口方法
@Override
public void m1() {
System.out.println("使用了m1的方法");
}
};
absAdapter.m1();
}
}
七、適配器模式的注意事項和細節
1)三種命名方式,是根據src是以怎樣的形式給到Adapter(在Adapter裏的形式)來命名的。
2)類適配器:以類給到,在Adapter裏,就是將src當作類,繼承;
對象適配器:以對象給到,在Adapter裏,將src作爲一個對象,持有;
接口適配器:以接口給到,在Adapter裏,將src作爲一個接口,實現。
3)Adapter模式最大的作用還是將原本不兼容的接口融合在一起工作。