設計模式學習筆記——適配器模式

適配器模式

適配器模式,將一個類的接口轉換成客戶希望的另外一個接口。Adapter模式使得原本由於接口不兼容而不能一起工作的那些類可以一起工作。

結構圖


代碼實現

Target:客戶期待的接口
/**
 * 客戶期待的接口
 * @author xukai
 * 2016年3月22日 下午12:57:38
 */
public class Target {

	public void request(){
		System.out.println("普通請求");
	}
	
}

Adaptee:需要適配的類
/**
 * 需要適配的類
 * @author xukai
 * 2016年3月22日 下午12:58:37
 */
public class Adaptee {

	public void specificRequest(){
		System.out.println("特殊請求");
		
	}
	
}

適配器類Adapter:
/**
 * 適配器類:將源接口裝換成目標接口
 * @author xukai
 * 2016年3月22日 下午12:59:15
 */
public class Adapter extends Target {

	private Adaptee adaptee = new Adaptee();
	
	@Override
	public void request() {
		adaptee.specificRequest();
	}
	
}
客戶端:
public class Client {

	public static void main(String[] args) throws ClassNotFoundException {
		Target target = new Adapter();
		target.request();
		
	}
	
}
Console:
特殊請求
對客戶端來說,調用的是Adapter的方法,實際上是調用的Adaptee的方法。
適配器一詞最早來自於電力行業中,如:每個國家的標準電壓不同,有的是220V,有的是110V,這個時候就需要適配器從中轉換一下。

demo

問題:姚明剛參加NBA的時候,不懂英文,聽不懂教練的指揮,使用適配器處理。

結構圖


代碼實現

球員類:
/**
 * 球員類
 * @author xukai
 * 2016年3月22日 下午1:25:23
 */
public abstract class Player {

	protected String name;
	
	public Player(String name) {
		this.name = name;
	}
	
	public abstract void attack();
	
	public abstract void defense();
}
每個具體位置的球員:
前鋒
/**
 * 前鋒
 * @author xukai
 * 2016年3月22日 下午1:34:51
 */
public class Forwards extends Player {

	public Forwards(String name) {
		super(name);
	}

	@Override
	public void attack() {
		System.out.println("前鋒" + name + "進攻");
	}

	@Override
	public void defense() {
		System.out.println("前鋒" + name + "防守");
	}

}
中鋒
/**
 * 中鋒
 * @author xukai
 * 2016年3月22日 下午11:18:21
 */
public class Center extends Player {

	public Center(String name) {
		super(name);
	}

	@Override
	public void attack() {
		System.out.println("中鋒" + name + "進攻");
	}

	@Override
	public void defense() {
		System.out.println("中鋒" + name + "防守");
	}

}
後衛
/**
 * 後衛
 * @author xukai
 * 2016年3月22日 下午1:45:49
 */
public class Guards extends Player {

	public Guards(String name) {
		super(name);
	}

	@Override
	public void attack() {
		System.out.println("後衛" + name + "進攻");
	}

	@Override
	public void defense() {
		System.out.println("後衛" + name + "防守");
	}

}
但是姚明屬於外籍中鋒
/**
 * 外籍中鋒
 * @author xukai
 * 2016年3月22日 下午1:46:40
 */
public class ForeignCenter {

	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	public void 進攻(){
		System.out.println("外籍中鋒" + name + "進攻");
	}
	
	public void 防守(){
		System.out.println("外籍中鋒" + name + "防守");
	}
	
}
需要適配器,翻譯者類:
/**
 * 翻譯者
 * @author xukai
 * 2016年3月22日 下午10:53:07
 */
public class Translator extends Player {

	private ForeignCenter wjzf = new ForeignCenter();
	
	public Translator(String name) {
		super(name);
		wjzf.setName(name);
	}

	@Override
	public void attack() {
		wjzf.進攻();
	}

	@Override
	public void defense() {
		wjzf.防守();
	}

}
客戶端:
public class Client {

	public static void main(String[] args) {
		Player b = new Forwards("巴蒂爾");
		b.attack();

		Player m = new Guards("麥克");
		m.attack();

		Player ym = new Translator("姚明");
		ym.attack();
		ym.defense();

	}

}
Console:
前鋒巴蒂爾進攻
後衛麥克進攻
外籍中鋒姚明進攻
外籍中鋒姚明防守
姚明聽不懂教練指揮,讓姚明立馬學習說英語,不行,讓教練說中文,也不行,只能中間添加一個翻譯員。

總結

當系統的數據和行爲都正確,但是接口不符時,可以考慮使用適配器,目的是使控制範圍之外的一個原有對象與某個接口匹配。
適配器模式主要應用於複用一些現存的類,但是接口又與複用環境要求不一致的情況。
使用一個已經存在的類,但它的接口,即方法和要求不相同時(兩個類所做的事情相同或者相似,但具有不同的接口),使用適配器模式,從而達到客戶代碼可以統一調用同一接口,簡單、直接、緊湊化。
發佈了94 篇原創文章 · 獲贊 66 · 訪問量 18萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章