Adapter模式

在現實世界中,如果想讓交流電220伏特的電源給直流12伏特的筆記本供電。我們會使用AC適配器。進行電流的轉化。在程序中也常常需要這樣的適配器。

在程序世界中,經常會有現有的程序無法直接使用,需要做適當的變換之後才能使用。

Adapter模式:用於填補“現有程序”和“所需程序”之間差異的設計模式。

Adapter模式有以下兩種:

1、類適配器模式(使用繼承的適配器)

2、對象適配器模式(使用委託的適配器)。

程序示例(1)(使用繼承的適配器)

package Class;

//現在是實際情況.220伏特的電源
public class Banner {

	private String string;
	public Banner(String string) {
		this.string=string;
	}
	public void showWithParent() {
		System.out.println("("+string+")");
	}
	public void showWithAster() {
		System.out.println("*"+string+"*");
	}
}
package Class;
//print接口。是“需求”的接口。12伏特的需求
public interface Print {
	public abstract void printWeak();
	public abstract void printStrong();
}
package Class;
//該類扮演適配器的角色。繼承類Banner類和裏面的方法。
//同時又實現了print接口
public class PrintBanner extends Banner implements Print {
	public PrintBanner(String string) {
		super(string);
	}
	public void printWeak() {
		showWithParent();
	}
	public void printStrong() {
		showWithAster();
	}
}
package Class;
//通過扮演適配器覺得的printBanner類來弱化(帶括號)或者強化(帶星號)Hello字符串的顯示
public class Main {
	public static void main(String[] args) {
		Print print=new PrintBanner("Hello");
		print.printWeak();
		print.printStrong();
	}

}

這裏將PrintBanner類實例保存在了Print類型的變量中,在Main類中,我們使用Print接口(即調用printWeak方法和printStrong方法)來進行編程的。對Main類代碼而言,Banner類、showWithParent方法和showWithAster方法被完全隱藏起來了。這就好像筆記本電腦只要在直流12伏特電壓下就能正常工作,但它並不知道12伏特的電壓是由適配器將220伏特電壓轉換而成的。

Main類並不知道PrintBanner類是如何實現的,這樣就可以不再對Main類進行修改的情況下改變PrintBanner類的具體實現。

注意使用接口類的使用原則。“不要使用具體類來編程,要優先使用抽象類和接口來編程”。

實例程序(2)(使用委託的示例程序)

關於委託:

委託:通俗來說就是“交給其他人”。在Java語言中,委託就是將某個方法中的實例處理交給其他實例的方法。(之前看到一篇文章寫的是C#的委託。裏面解釋的是C#中因爲沒有函數指針這個東西,所以使用了這個委託的形式。)

Main類和Banner類與示例1完全相同。不過這裏假設Print不是藉口而是類。

其實這裏的委託就是委託給了Bannner實例。而PrintBanner不再是繼承Bannner和實現Print接口。改成了繼承Print類。進而在程序中使用Banner的實例進行調用Bannner中的方法。

package Class;
//print接口。是“需求”的接口。12伏特的需求
public abstract class Print {
	public abstract void printWeak();
	public abstract void printStrong();
}
package Class;
//該類扮演適配器的角色。繼承類Banner類和裏面的方法。
//同時又實現了print接口
public class PrintBanner extends Print {
	private Banner banner;
	public PrintBanner(String string) {
		this.banner=new Banner(string);
	}
	public void printWeak() {
		banner.showWithParent();
	}
	public void printStrong() {
		banner.showWithAster();
	}
}

Adapter模式中的登場角色

在adapter模式中有以下登場角色

1、Target(對象)

該角色負責定義所需的方法。例:12伏特的直流電源電壓。在示例程序中,由Print接口和Print類扮演此角色。

2、Clinet(請求者)

該角色負責使用Target角色所定義的方法進行具體處理。例:直流12伏特驅動的筆記本。在示例程序中,由Main類扮演此角色。

3、Adaptee(被適配)

Adaptee是一個持有既定方法的角色。例:220伏特的交流電源。在程序示例中是Bannner。

如果Adaptee角色中方法與Target角色方法相同,就不需要接下來的Adapter角色了。

4、Adapter(適配器)

Adapter模式的主人公。使用Adapter角色的方法來滿足Target角色的需求,這是Adapter模式的目的,也就是Adapter角色的作用。在示例程序中是PrintBanner。

在類適配器模式中,Adapter角色通過集成來使用Adaptee角色。而在對象適配器模式中Adapter角色通過委託來使用Adapter角色。

拓展思路要點

1、什麼使用使用Adapter模式

Adapter模式會對現有類進行適配,生成新的類。通過該模式可以很方便地創建我們需要的方法羣。當出現bug的時候,由於我們很明確地知道了bug不在現有類(Adaptee角色)中,所以只需要扮演Adapter角色的類即可。這樣一來,代碼問題排查就會變得非常簡單。

2、如果沒有現成的代碼讓現有類適配新的接口時,使用Adapter模式似乎理所當然。不過實際上,我們在使用現有類適配新的接口時,常會有將這裏稍微修改一下就好了。但是如果對已測試的代碼進行修改,就必須重新進行測試。

使用Adapter模式可以在完全不改變現有代碼的前提下使用吸納有代碼適配接口。此外,在Adapter中並非需要知道現成代碼,只要知道類的功能,就可以編寫出新的類。

3、版本升級與兼容

在版本升級的時候常出席那“與舊版本兼容性”問題,現實中又不能完全拋棄舊版本。這是就可以使用Adapter模式使新舊版本兼容。幫助我們輕鬆的維護新版本與舊版本、

例如:今後只想維護新版本,就可以讓新版本扮演Adaptee的角色,舊版本扮演Target的角色。接着編寫Adapter角色的類,讓它使用新版本來實現舊版本的類的方法。

相關的模式

1、Bridge模式

Adapter模式用於連接接口不同的類,而Bridge模式則用於連接類的功能層次結構與實現層次結構。

2、Decorator模式

Adapter用於填補不用接口之間的縫隙,而Decorator,模式則是在不改變接口的前提下增加功能。

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