java設計模式之 適配器模式

package com.lennon.mini.test;

/*
 * 適配器模式(類模式)
 * 
 * 目的:是爲了將不合適的接口(通常是爲了迎合特殊需求)通過適配的方式獲得一個可使用的新的特殊接口(符合開閉原則)
 * 
 * 應用場景:若是當前有一個二孔的插座,而你的電源線是三叉的,那麼狠明顯,你的電源線沒法直接使用這個二孔插座,可是在多數狀況下
 * 		它是可使用的。可是在特殊的請況下,它沒法知足新的需求,故而你須要在買一個二孔轉三孔的插座來知足這需求。
 * 		通常狀況下,多數爲已發佈的接口沒法知足,卻又沒法直接修改,因此才須要使用這種辦法啦~~
 * 
 * 缺點:過多的適配器會讓整個系統的設計更加凌亂。
 * 
 * 建議:若是你的系統只是少數的使用了這個適配器,在容許範圍內,你可使用它,
 * 		若是你的系統將會大量使用,那麼請重構你的代碼吧!
 * 
 */
public class LennonAdapter extends Adaptee implements Target {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}

	@Override
	public void sankong() {
		/*
		 * 三孔實現代碼,若是須要調用二孔方法,則直接使用super.erkong來修改
		 */
		
	}

}


/*
 * 適配器模式(對象模式)
 * 
 * 目的:利用組合的優點,在新合成的類中加入私有域 被適配類的對象,在對象中調用來重用舊有代碼。
 * 
 * 應用場景:在這種狀況下,令得新類與舊有的類的耦合度更高,可是很明顯,這種組合關係令得新類與舊有類之間並不存在繼承的關係
 * 		因此缺失了繼承的優勢,卻也沒有了繼承的缺點。它比類的適配模式無疑是更好,畢竟在最佳實踐上來講,前輩們都推薦使用組合優於繼承
 * 		不過凡事不必定吧。兩者之間的好壞,關鍵點仍是得取決於具體的需求。
 * 
 *類適配器和對象適配器的權衡

  ●  類適配器使用對象繼承的方式,是靜態的定義方式;而對象適配器使用對象組合的方式,是動態組合的方式。

  ●  對於類適配器,因爲適配器直接繼承了Adaptee,使得適配器不能和Adaptee的子類一塊兒工做,由於繼承是靜態的關係,當適配器繼承了Adaptee後,就不可能再去處理  Adaptee的子類了。

     對於對象適配器,一個適配器能夠把多種不一樣的源適配到同一個目標。換言之,同一個適配器能夠把源類和它的子類都適配到目標接口。由於對象適配器採用的是對象組合的關係,只要對象類型正確,是否是子類都無所謂。

  ●   對於類適配器,適配器能夠重定義Adaptee的部分行爲,至關於子類覆蓋父類的部分實現方法。

     對於對象適配器,要重定義Adaptee的行爲比較困難,這種狀況下,須要定義Adaptee的子類來實現重定義,而後讓適配器組合子類。雖然重定義Adaptee的行爲比較困難,可是想要增長一些新的行爲則方便的很,並且新增長的行爲可同時適用於全部的源。

  ●  對於類適配器,僅僅引入了一個對象,並不須要額外的引用來間接獲得Adaptee。

     對於對象適配器,須要額外的引用來間接獲得Adaptee。

  建議儘可能使用對象適配器的實現方式,多用合成/聚合、少用繼承。固然,具體問題具體分析,根據須要來選用實現方式,最適合的纔是最好的。

適配器模式的優勢
  更好的複用性
  系統須要使用現有的類,而此類的接口不符合系統的須要。那麼經過適配器模式就可讓這些功能獲得更好的複用。

  更好的擴展性
  在實現適配器功能的時候,能夠調用本身開發的功能,從而天然地擴展系統的功能。
 * 
 */
class LennonAdapterObject implements Target{

	Adaptee adaptee;
	
	//Adaptee adaptee = new Adaptee()
	//工廠模式也可使用
	
	public LennonAdapterObject(Adaptee adaptee) {
		// TODO Auto-generated constructor stub
		//this.adaptee = new Adaptee(adaptee);
		this.adaptee = adaptee;
	}
	
	@Override
	public void erkong() {
		// TODO Auto-generated method stub
		adaptee.erkong();
	}

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

/*
 * 目的:根據插座案例來講,這個接口的目的就是實現將二孔轉三孔的插座的一個抽象接口
 * 
 * 設計:通常它具有了被適配的二孔的插座類的方法,同是它具有了三孔的插座的方法。實現這個類,就能夠具有了二孔以及三孔的方法
 * 
 */
interface Target {
	public void erkong();
	public void sankong();
}

/*
 * 目的:它是一個已經發布的接口,已經沒法再對其進行修改,除非整個系統進行全方位重構,那就是一個新的項目了
 * 
 * 設計:它是知足舊有需求的接口,可是新的需求超越了它最大的擴張機制(加入它存在必定的擴展方法)
 * 		在使用的時候,只能經過適配模式適配出一個嶄新的接口來知足新的需求
 */
class Adaptee {

	public void erkong(){
		/*
		 * 這裏是二孔顯示的全部細節,若是它很是的龐大,那麼與面向對象工做者的義不容辭的應該考慮重用這段代碼,
		 */
	}
	
	
}

//在適配器中,還有一個缺省適配器
/*
 * 缺省適配(Default Adapter)模式爲一個接口提供缺省實現,
 * 這樣子類型能夠從這個缺省實現進行擴展,而沒必要從原有接口進行擴展。
 * 做爲適配器模式的一個特例,缺省是適配模式在JAVA語言中有着特殊的應用。
 * 
 * 以學生爲例
 * 
 */
interface Student {
	
	//讀書
	public void read();
	
	//寫字
	public void write();
	
	
}

/*
 * 通常的學生都會讀書寫字,可是若是是一個殘障學生,他只能寫,卻沒法發音呢?
 * 		(  對不起,用了這麼一個例子,只是正好剛剛看完青年文摘,
 * 		以爲社會對於殘障人士的關愛還不足,但願能夠更多的人去關注殘障人士,
 * 		但願更有能力的人能夠回饋給社會更多,也但願做爲健全的咱們,更應該爲夢想去堅持,不應怨天尤人)
 * 
 * 
 * 顯然,若是殘障學生去繼承普通學生的這個接口,是不對的,由於他被上帝殘忍的剝奪了這項權利
 */

class Disabler  {
	public void write(){}
}

//如此一來,缺省適配器就出現了

/*
 * 抽象類實現了學生這接口,而他則做爲全部的殘障學生的抽象基類人存在,好比學生能夠讀書卻不能寫字,或者能寫字卻不能讀書
 */
abstract class DisableStudent implements Student {
	//讀書
	public void read(){}
		
		//寫字
	public void write(){}
}

/*
 * 如此一來
 * 利用抽象繼承體系對缺省部分進行隱藏,在使用時類型還能夠提供向上轉型爲抽象基類類型,可是,最好仍是使用子類,由於他的語義更加清晰
 * 
 * 在不少狀況下,必須讓一個具體類實現某一個接口,可是這個類又用不到接口所規定的全部的方法。一般的處理方法是,這個具體類要實現全部的方法,
 * 那些有用的方法要有實現,那些沒有用的方法也要有空的、平庸的實現。這些空的方法是一種浪費,有時也是一種混亂。
 * 除非看過這些空方法的代碼,程序員可能會覺得這些方法不是空的。即使他知道其中有一些方法是空的,
 * 也不必定知道哪些方法是空的,哪些方法不是空的,除非看過這些方法的源代碼或是文檔。缺省適配模式能夠很好的處理這一狀況。
 * 能夠設計一個抽象的適配器類實現接口,此抽象類要給接口所要求的每一種方法都提供一個空的方法。此抽象類可使它的具體子類免於被迫實現空的方法。
class Disabler extends DisableStudent  {
	public void write(){}
}

 */

博文參考連接html

http://www.cnblogs.com/java-my-life/archive/2012/04/13/2442795.htmljava

相關文章
相關標籤/搜索