介面卡模式(類介面卡,物件介面卡,介面介面卡)

馬化騰的爸爸碼ming發表於2020-12-09

現實生活中的介面卡例子

泰國插座用的是兩孔的(歐標),可以買個多功能轉換插頭(介面卡) ,這樣就可以使用了。
在這裡插入圖片描述

基本介紹

  1. 介面卡模式(Adapter Pattern)將某個類的介面轉換成客戶端期望的另一個介面表示,主的目的是相容性,讓原本因介面不匹配不能一起工作的兩個類可以協同工作。其別名為包裝器(Wrapper)
  2. 介面卡模式屬於結構型模式
  3. 主要分為三類:類介面卡模式、物件介面卡模式、介面介面卡模式

工作原理

  1. 介面卡模式:將一個類的介面轉換成另一種介面.讓原本介面不相容的類可以相容
  2. 從使用者的角度看不到被適配者,是解耦的
  3. 使用者呼叫介面卡轉化出來的目標介面方法,介面卡再呼叫被適配者的相關介面方法
  4. 使用者收到反饋結果,感覺只是和目標介面互動,如圖
    在這裡插入圖片描述

類介面卡模式

類介面卡模式介紹

基本介紹:Adapter 類,通過繼承src 類,實現dst 類介面,完成src->dst 的適配。

類介面卡模式應用例項

  1. 應用例項說明
    以生活中充電器的例子來講解介面卡,充電器本身相當於Adapter,220V 交流電相當於src (即被適配者),我們的目dst(即目標)是5V 直流電
  2. 思路分析(類圖)
    在這裡插入圖片描述
  3. 程式碼實現

IVoltage5V.java:適配介面(需要的)

//適配介面
public interface IVoltage5V {
	public int output5V();
}

Voltage220V.java:被適配的類(要轉換的)

//被適配的類
public class Voltage220V {
	//輸出220V的電壓
	public int output220V() {
		int src = 220;
		System.out.println("電壓=" + src + "伏");
		return src;
	}
}

VoltageAdapter.java:介面卡類(轉換器)

//介面卡類
public class VoltageAdapter extends Voltage220V implements IVoltage5V {

	@Override
	public int output5V() {
		// TODO Auto-generated method stub
		//獲取到220V電壓
		int srcV = output220V();
		int dstV = srcV / 44 ; //轉成 5v
		return dstV;
	}

}

Phone.java

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, 不能充電~~");
		}
	}
}

Client.java

public class Client {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println(" === 類介面卡模式 ====");
		Phone phone = new Phone();
		phone.charging(new VoltageAdapter());
	}

}

類介面卡模式注意事項和細節

  1. Java 是單繼承機制,所以類介面卡需要繼承src 類這一點算是一個缺點, 因為這要求dst 必須是介面,有一定侷限性;
  2. src 類的方法在Adapter 中都會暴露出來,也增加了使用的成本。
  3. 由於其繼承了src 類,所以它可以根據需求重寫src 類的方法,使得Adapter 的靈活性增強了。

物件介面卡模式

物件介面卡模式介紹

  1. 基本思路和類的介面卡模式相同,只是將Adapter 類作修改,不是繼承src 類,而是持有src 類的例項,以解決相容性的問題。即:持有src 類,實現dst 類介面,完成src->dst 的適配
  2. 根據“合成複用原則”,在系統中儘量使用關聯關係(聚合)來替代繼承關係
  3. 物件介面卡模式是介面卡模式常用的一種

物件介面卡模式應用例項

  1. 應用例項說明
    以生活中充電器的例子來講解介面卡,充電器本身相當於Adapter,220V 交流電相當於src (即被適配者),我們的目dst(即目標)是5V 直流電,使用物件介面卡模式完成。
  2. 思路分析(類圖):只需修改介面卡即可, 如下:
    在這裡插入圖片描述
  3. 程式碼實現(只改了客戶端和介面卡類:介面卡類改為聚合關係

VoltageAdapter.java

//介面卡類
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;
		
	}

}

Client.java

public class Client {

	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. 使用成本更低,更靈活。

介面介面卡模式

介面介面卡模式介紹

  1. 一些書籍稱為:介面卡模式(Default Adapter Pattern)或預設介面卡模式
  2. 核心思路:當不需要全部實現介面提供的方法時,可先設計一個抽象類實現介面,併為該介面中每個方法提供一個預設實現(空方法),那麼該抽象類的子類可有選擇地覆蓋父類的某些方法來實現需求
  3. 適用於一個介面不想使用其所有的方法的情況。

最簡單的例項

  1. 類圖:
    在這裡插入圖片描述
    2)程式碼實現:

Interface4.java

public interface Interface4 {
	public void m1();
	public void m2();
	public void m3();
	public void m4();
}

AbsAdapter.java

//在AbsAdapter 我們將 Interface4 的方法進行預設實現
public abstract class AbsAdapter implements Interface4 {

	//預設實現
	public void m1() {
	}

	public void m2() {
	}

	public void m3() {
	}

	public void m4() {
	}
}

Client.java

public class Client {
	public static void main(String[] args) {
		
		AbsAdapter absAdapter = new AbsAdapter() {
			//只需要去覆蓋我們 有需要地使用 介面方法
			@Override
			public void m1() {
				// TODO Auto-generated method stub
				System.out.println("使用了m1的方法");
			}
		};
		
		absAdapter.m1();
	}
}

介面介面卡模式應用例項

1)Android中的屬性動畫ValueAnimator類(略)

介面卡模式在SpringMVC 框架應用的原始碼剖析

  1. SpringMvc 中的HandlerAdapter, 就使用了介面卡模式
  2. SpringMVC 處理請求的流程回顧
  3. 使用HandlerAdapter 的原因分析:
    可以看到處理器的型別不同,有多重實現方式,那麼呼叫方式就不是確定的,如果需要直接呼叫Controller 方法,需要呼叫的時候就得不斷是使用if else 來進行判斷是哪一種子類然後執行。那麼如果後面要擴充套件Controller,就得修改原來的程式碼,這樣違背了OCP 原則。
  4. 程式碼分析+Debug 原始碼
    在這裡插入圖片描述
  5. 動手寫SpringMVC通過介面卡設計模式獲取到對應的Controller的原始碼
    1)類圖:
    在這裡插入圖片描述
    2)程式碼實現

說明
• Spring定義了一個適配介面,使得每一種Controller有一種對應的介面卡實現類
• 介面卡代替controller執行相應的方法
• 擴充套件Controller 時,只需要增加一個介面卡類就完成了SpringMVC的擴充套件了,
• 這就是設計模式的力量

介面卡模式的注意事項和細節

  1. 三種命名方式,是根據src 是以怎樣的形式給到Adapter(在Adapter 裡的形式)來命名的。
  2. 類介面卡:以類給到,在Adapter 裡,就是將src 當做類,繼承
    物件介面卡:以物件給到,在Adapter 裡,將src 作為一個物件,持有
    介面介面卡:以介面給到,在Adapter 裡,將src 作為一個介面,實現
  3. Adapter 模式最大的作用還是將原本不相容的介面融合在一起工作。
  4. 實際開發中,實現起來不拘泥於我們講解的三種經典形式

相關文章