設計模式 適配器模式的寫法及分析

設計模式分類

  1. 創建型模式:單例模式抽象工廠模式原型模式建造者模式工廠模式

  2. 結構型模式:適配器模式、橋接模式、裝飾模式、組合模式、外觀模式、享元模式、代理模式。

  3. 行爲型模式:模版方法模式、命令模式、訪問者模式、迭代器模式、觀察者模式、中介者模式、備忘錄模式、解釋器模式(Interpreter 模式)、狀態模式、策略模式、職責鏈模式(責任鏈模式)。

適配器模式

基本介紹

  1. 適配器模式(Adapter Pattern)將某個類的接口轉換成客戶端期望的另一個接口表示,主的目的是兼容性,讓原本因接口不匹配不能一起工作的兩個類可以協同工作。其別名爲包裝器(Wrapper)

  2. 適配器模式屬於結構型模式

  3. 主要分爲三類:類適配器模式、對象適配器模式、接口適配器模式

類適配器模式

工作原理

  1. 適配器模式:將一個類的接口轉換成另一種接口。讓原本接口不兼容的類可以兼容

  2. 從用戶的角度看不到被適配者,是解耦的

  3. 用戶調用適配器轉化出來的目標接口方法,適配器再調用被適配者的相關接口方法

  4. 用戶收到反饋結果,感覺只是和目標接口交互

需求

在現實生活中,我們日常使用的電網都是220V的,但是我們的手機充電電壓卻比較低,期間需要一個適配過渡的過程。

UML類圖

public class Client {
	public static void main(String[] args) {
		Phone phone = new Phone();
		phone.charge(new VoltageAdapter());
	}
	
}

//電壓220V輸出類
class Volatage220V {
	public int output220V() {
		int src = 220;
		System.out.println("電壓:"+ src +"V");
		return src;
	}
}

// 電壓5V輸出接口
interface Voltage5V {
	int output5V();
}

// 電壓適配器類
class VoltageAdapter extends Volatage220V implements Voltage5V {

	@Override
	public int output5V() {
		int srcV = output220V();
		int dstV = srcV / 44;
		System.out.println("類適配器:將220V電壓轉換爲5V");
		return dstV;
	}
}

// 手機
class Phone {
	public void charge(Voltage5V voltage5V) {
		int output5v = voltage5V.output5V();
		if(output5v == 5) {
			System.out.println("電壓5V,開始充電");
		}else {
			System.out.println("電壓不是5V,不充電");
		}
	}
}

結果

注意事項和細節

  1. Java是單繼承機制,所以類適配器需要繼承src類這一點算是一個缺點, 因爲這要求dst必須是接口,有一定侷限性;

  2. src類的方法在Adapter中都會暴露出來,也增加了使用的成本。

  3. 由於其繼承了src類,所以它可以根據需求重寫src類的方法,使得Adapter的靈活性增強了。

對象適配器

工作原理

  1. 基本思路和類的適配器模式相同,只是將Adapter類作修改,不是繼承src類,而是持有src類的實例,以解決兼容性的問題。 即:持有 src類,實現 dst 類接口,完成src->dst的適配

  2. 根據“合成複用原則”,在系統中儘量使用關聯關係來替代繼承關係。

  3. 對象適配器模式是適配器模式常用的一種

需求和類適配器一樣,我們來用對象適配器模擬一下剛剛的流程

UML類圖

public class Client {
	public static void main(String[] args) {
		Phone phone = new Phone();
		phone.charge(new VoltageAdapter(new Volatage220V()));
	}
}

//電壓220V輸出類
class Volatage220V {
	public int output220V() {
		int src = 220;
		System.out.println("電壓:"+ src +"V");
		return src;
	}
}
// 電壓5V輸出接口
interface Voltage5V {
	int output5V();
}
// 電壓適配器類
class VoltageAdapter implements Voltage5V {

	Volatage220V volatage220V;
	
	
	public VoltageAdapter(Volatage220V volatage220v) {
		volatage220V = volatage220v;
	}

	@Override
	public int output5V() {
		if(volatage220V != null) {
			int srcV = volatage220V.output220V();
			int dstV = srcV / 44;
			System.out.println("對象適配器:將220V電壓轉換爲5V");
			return dstV;
		}
		return 0;
	}
}
// 手機
class Phone {
	public void charge(Voltage5V voltage5V) {
		int output5v = voltage5V.output5V();
		if(output5v == 5) {
			System.out.println("電壓5V,開始充電");
		}else {
			System.out.println("電壓不是5V,不充電");
		}
	}
}

 結果

注意事項和細節

  1. 對象適配器和類適配器其實算是同一種思想,只不過實現方式不同。 根據合成複用原則,使用組合替代繼承, 所以它解決了類適配器必須繼承src的侷限性問題,也不再要求dst必須是接口。

  2. 使用成本更低,更靈活

接口適配器模式

工作原理

  1. 一些書籍稱爲:適配器模式(Default Adapter Pattern)或缺省適配器模式。

  2. 當不需要全部實現接口提供的方法時,可先設計一個抽象類實現接口,併爲該接口中每個方法提供一個默認實現(空方法),那麼該抽象類的子類可有選擇地覆蓋父類的某些方法來實現需求

UML類圖

public class User {
	public static void main(String[] args) {
		//選擇性實現對應方法即可
		new AbsAdapter() {

			@Override
			public void operation1() {
				// TODO Auto-generated method stub
			}

			@Override
			public void operation3() {
				// TODO Auto-generated method stub
				super.operation3();
			}
			
		};
	}
}
// 
interface Interface {
	void operation1();
	void operation2();
	void operation3();
	void operation4();
}
// 接口適配,實現所有接口,方法置空
abstract class AbsAdapter implements Interface{
	public void operation1() {}
	public void operation2() {}
	public void operation3() {}
	public void operation4() {}
	
}

適用場景

適用於一個接口不想使用其所有的方法的情況

總結

  1. 三種命名方式,是根據 src是以怎樣的形式給到Adapter(在Adapter裏的形式)來 命名的。

  2. 類適配器:以類給到,在Adapter裏,就是將src當做類,繼承 對象適配器:以對象給到,在Adapter裏,將src作爲一個對象,持有 接口適配器:以接口給到,在Adapter裏,將src作爲一個接口,實現

  3. Adapter模式最大的作用還是將原本不兼容的接口融合在一起工作。

  4. 實際開發中,實現起來不拘泥於我們講解的三種經典形式

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章