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