設計模式-6.適配器模式

1. 定義:

適配器模式的定義是,Convert the interface of a class into another interface clients expect,將某個類的接口轉換爲接口客戶所需的類型。適配器模式解決的問題是,使得原本由於接口不兼容而不能一起工作、不能統一管理的那些類可以在一起工作、可以進行統一管理。將一個接口轉換成客戶希望的另一個接口,適配器模式使接口不兼容的那些類可以一起工作,其別名爲包裝器。

個人覺得這些定義不太容易理解,但是我找到一句話,覺得更符合我對適配器模式的理解:適配器是爲了不改變有的代碼實現,但是又要滿足現有的需求,更像是屬於一種被動選擇。

Adapter模式的宗旨:保留現有類所提供的服務,向客戶提供接口,以滿足客戶的期望

2.先舉一個例子,現在有一個方法,而這個方法可以產生220V的電壓,然後我買了一個手機,手機充電電壓是5V,如何用220V的方法給5V的手機充電,同時有又不改變原有的220V電壓的方法。那麼我就需要一個手機充電器來作爲適配,將220V電壓,轉化爲5V的電壓,手機充電器就是適配器類。(注意,不要對我舉例產生固有思維,舉例只是爲了形象理解,事實上適配器就是爲了:保留現有類所提供的服務,向客戶提供接口,以滿足客戶的期望

2.1 適配器有類 適配器 和 對象適配器

以上面的例子來實現類適配器代碼,先有一個供電站接口,各個地區供電站都可以實現這個接口,提供不同的電壓

/**
 * 供電站 接口
 * @author lx
 *
 */
public interface PowerStation {
	/**
	 * 供電接口 返回電壓
	 * @return
	 */
	public int providePower();
}

2.2.現有亳州供電站爲用戶提供220V電壓供電,具體實現

public class BoZhouPowerStation implements PowerStation{

	@Override
	public int providePower() {
		// 我這裏舉例比代碼較少,一般項目中可能有複雜的業務邏輯
		return 220;
	}

}

2.3.現在我手機沒電了,想要給手機充電,我就多寫一個手機充電接口

/**
 * 手機充電接口
 * @author lx
 *
 */
public interface PhoneCharge {

	public String chargePower();
}

2.4.我要給我的華爲手機充電,華爲手機實現手機充電接口,具有充電的能力,但是需要5V電壓進行充電,但是我們只有220V電壓的實現類,當電壓實現類是比較複雜的,就像亳州供電站一樣,不可能爲了手機充電,提供一個5V電壓供電站。(如果在代碼中,類似於電壓實現類比較簡單,也可以實現供電站接口,提供一個5V的電壓 ,直接調用即可)

public class HuaWeiPhone implements PhoneCharge{
        
        //需要5V電壓進行充電
	@Override
	public String chargePower() {
		
		return null;
	}

}

現在需要對上述代碼進行改造,保持原有220V電壓實現類不變,因爲可能有其它地方調用,改造後的代碼


public class HuaWeiPhone extends BoZhouPowerStation implements PhoneCharge{

	@Override
	public String chargePower() {
		//獲取220v電壓操作
		int voltage = this.providePower();
		//將電壓轉化爲5v操作
		int phoneVoltage = voltage/44;
		System.out.println("通過亳州供電站爲華爲手機充電,電壓:"+phoneVoltage+"V");
		return phoneVoltage+"V";
	}

}

我們new 一個華爲手機對象,執行上述方法,即可爲華爲手機充電。上述通過繼承實現兩個接口的連接,即爲類適配器模式,這種模式的缺點會增加代碼的耦合性,不太靈活。

3.對象適配器模式 代碼 現在我使用小米手機,充電需要10V電壓

public class XiaoMiPhone implements PhoneCharge{

	public BoZhouPowerStation bzs;
	
	public XiaoMiPhone() {
		bzs = new BoZhouPowerStation();
	}
	
	@Override
	public String chargePower() {
		//獲取220v電壓操作
		int voltage = bzs.providePower();
		//將電壓轉化爲10v操作
		int phoneVoltage = voltage/22;
		System.out.println("同過亳州供電站獲取手機充電電壓:"+phoneVoltage+"V");
		return phoneVoltage+"V";
	}

 4. 上述實現方式不太好的地方在與,我的小米手機只能使用亳州供電站,並且這個亳州供電站還是小米充電器自帶的。還是不夠靈活,修改爲如下:

public class XiaoMiPhone implements PhoneCharge{

	public BoZhouPowerStation bzs;
	
	public XiaoMiPhone(BoZhouPowerStation bzs) {
		this.bzs = bzs;
	}
	
	@Override
	public String chargePower() {
		//獲取220v電壓操作
		int voltage = bzs.providePower();
		//將電壓轉化爲10v操作
		int phoneVoltage = voltage/22;
		System.out.println("同過亳州供電站獲取手機充電電壓:"+phoneVoltage+"V");
		return phoneVoltage+"V";
	}

}

5.上述代碼,也不夠靈活,雖然亳州供電站不用在代碼內部創建了,但是我出差到上海想使用上供電站的電對我的手機進行充電,需要做如下修改:

public class XiaoMiPhone implements PhoneCharge{

	public PowerStation ps;
	
	public XiaoMiPhone(PowerStation ps) {
		this.ps = ps;
	}
	
	@Override
	public String chargePower() {
		//獲取220v電壓操作
		int voltage = ps.providePower();
		//將電壓轉化爲10v操作
		int phoneVoltage = voltage/22;
		System.out.println("同過亳州供電站獲取手機充電電壓:"+phoneVoltage+"V");
		return phoneVoltage+"V";
	}

}

6.適配器模式的使用場景

(1)其中一個使用的場景是像上面所說的一樣,有兩個接口,你主動的想去連接着兩個接口,寫個適配器,感覺這種情況也不是很多,因爲很多時候都是些一個實體類對象調用另一個實體類對象。

(2)被動使用的情況比較多。舉個栗子,你開發新版本的時候重新定義了接口,要和舊版本寫適配的時候,爲了方便也可以使用適配器模式。

 

 

 

 

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