天天看點

設計模式學習筆記——擴充卡模式擴充卡模式

擴充卡模式

擴充卡模式,将一個類的接口轉換成客戶希望的另外一個接口。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:

前鋒巴蒂爾進攻
後衛麥克進攻
外籍中鋒姚明進攻
外籍中鋒姚明防守
           

姚明聽不懂教練指揮,讓姚明立馬學習說英語,不行,讓教練說中文,也不行,隻能中間添加一個翻譯員。

總結

當系統的資料和行為都正确,但是接口不符時,可以考慮使用擴充卡,目的是使控制範圍之外的一個原有對象與某個接口比對。 擴充卡模式主要應用于複用一些現存的類,但是接口又與複用環境要求不一緻的情況。 使用一個已經存在的類,但它的接口,即方法和要求不相同時( 兩個類所做的事情相同或者相似,但具有不同的接口),使用擴充卡模式,進而達到客戶代碼可以統一調用同一接口,簡單、直接、緊湊化。

繼續閱讀