<大話設計模式>本教程說明及著作權聲明
l 該文檔參考和使用了網路上的免費開放的圖片和內容,並以免費開放的方式發布,希望為移動互連網和智能手機時代貢獻綿薄之力!可以隨意轉載,但不得使用該文檔謀利。
l 如果對該文檔有任何疑問或者建議,請進入官方部落格
http://www.cnblogs.com/guoshiandroid/留言或者直接與國士工作室聯絡(後附連絡方式),我們會謹慎參考您的建議並根據需要對本文檔進行修改,以造福更多開發人員!
l 《大話設計模式》的最新及完整內容會在國士工作室官方部落格定期更新,請訪問國士工作室部落格
http://www.cnblogs.com/guoshiandroid/擷取更多更新內容。
國士工作室是一支專註於Android平台企業級應用開發的技術團隊,致力於做中國最棒的Android應用程式開發機構,提供最棒的Android企業級應用開發培訓服務。
企業培訓和開發合作官方連絡方式:
電話:18610086859
Email:hiheartfirst@gmail.com
QQ:1740415547
QQ群:148325348
國士工作室 有你更美好!
查看其他部分:本教程整體說明及章節索引
本文PDF下載連結
MM的生日
抽象原廠模式應用情境舉例:
時光甜蜜的飛逝,GG和MM過著童話般的王子和公主的浪漫的生活。眼看MM生日就要到了,GG著急了。畢竟,這是自己的第一個女朋友的第一個生日啊。想了千萬種方法,問了身邊很多朋友,這個傻GG最終還是沒有確定最終該如何去做~~~~(>_<)~~~~
哎!愛,總是想到太多做的太少^_^
都快夜裡十二點了,GG還在Google和百度上面查詢如何給自己的Sweatheart過生日。此時,突然手機簡訊鈴聲響了,開啟一看,上面寫道:“親愛的,我知道這些天你一直在想我們如何一切過生日,其實,一切都很簡單的。簡單就好。”,看完簡訊,GG頓時全身暖流湧動,感覺好幸福^_^,有如此體貼理解人的MM,夫複何求( ⊙ o ⊙ )啊!剛要回複簡訊,手機鈴聲又響了,上面寫道:“我們還去麥當勞吧,不過這次使我們倆,要換一個地方,到華聯那邊的麥當勞吧^_^”,GG讀著簡訊,感動的無語了。簡訊回覆道:“一切惟老婆大人之命是從:-O”。GG和MM都沉浸在甜蜜和幸福中^_^
抽象原廠模式解釋:
抽象原廠模式(Abstact Factory Pattern)是所有形態的原廠模式中最為抽象和最其一般性的。抽象原廠模式可以向用戶端提供一個介面,使得用戶端在不必指定產品的具體類型的情況下,能夠建立多個產品族的產品對象。
抽象工廠中方法對應產品結構,具體工廠對應產品族
英文定義為:Provide an interface forcreating families of related or dependent objects without specifying theirconcrete classes.
抽象原廠模式的UML圖:
抽象原廠模式模式中包含的角色及其相應的職責如下:
抽象工廠(Creator)角色:抽象原廠模式的核心,包含對多個產品結構的聲明,任何工廠類都必須實現這個介面。
具體工廠(Concrete Creator)角色: 具體工廠類是抽象工廠的一個實現,負責執行個體化某個產品族中的產品對象。
抽象(Product)產品角色:抽象模式所建立的所有對象的父類,它負責描述所有執行個體所共有的公用介面。
具體產品(Concrete Product)角色:抽象模式所建立的具體執行個體對象。
抽象原廠模式深入分析:
抽象原廠模式是在當產品有多個 抽象角色的時候使用的一種建立型設計模式。
按照裡氏代換原則,凡是父類適用的地方,子類也必然適用。而在實際系統中,我們需要的是和父類類型相同的子類的執行個體對象,而不是父類本身,也就是這些抽象產品的具體子類的執行個體。具體工廠類就是來負責建立抽象產品的具體子類的執行個體的。
當每個抽象產品都有多於一個的具體子類的時候,工廠角色是如何確定執行個體化哪一個子類呢?例如說有兩個抽象產品角色,而每個抽象產品角色都有兩個具體產品。抽象原廠模式提供兩個具體工廠角色,分別對應於這兩個具體產品角色,每一個具體工廠角色只負責某一個產品角色的執行個體化。每一個具體工廠類只負責建立抽象產品的某一個具體子類的執行個體。
每一個模式都是針對一定問題的解決方案,Factory 方法模式針對的是一個產品等級結構;而抽象原廠模式針對的是多個產品等級結構。
何謂產品族?產品族是指位於不同產品等級結構中,功能相關聯的產品組成的家族。一般是位於不同的等級結構中的相同位置上。顯然,每一個產品族中含有產品的數目,與產品等級結構的數目是相等的,形成一個二維的座標系,水平座標是產品等級結構,縱座標是產品族。
對於每一個產品族,都有一個具體工廠。而每一個具體工廠建立屬於同一個產品族,但是分屬於不同等級結構的產品。
通過引進抽象原廠模式,可以處理具有相同(或者相似)等級結構的多個產品族中的產品對象的建立問題。
由於每個具體工廠角色都需要負責不同等級結構的產品對象的建立,因此每個工廠角色都需要提供相應數目的Factory 方法,分別用於建立相應數目的等級結構的產品。
如所示:
抽象原廠模式使用情境分析及代碼實現:
MM過生日的時候還是要到麥當勞,但是這次要求是到華聯那邊的麥當勞去,就是地方不同了,要換換口味和心情。這就是抽象原廠模式的一個很好的體現。首先對不同的麥當勞分店而言,每一種產品,例如說漢堡,都是漢堡,但是每個地方的漢堡在遵循統一標準的前提下又會儘力突出自己的特色,這樣這樣才能更好的吸引和留住顧客,因為不同的地方,隨著環境等的不同,人們的喜好和口味等都會有所不同,但是無論怎麼不同,始終還是漢堡,具有漢堡的準系統。同時,每一個分店都有一系列的產品,例如漢堡、雞翅等等,這就構成了產品的等級結構。
總之:麥當勞總部相當於抽象工廠,每個分店相當於具體工廠,而每種產品又有所不同。這樣在既保持了統一性的前提下,又使得各分店的特色有所不同,適合於吸引和留住不同環境下的客戶。
UML模型圖如下所示:
具體實現代碼如下:
建立立一個食物的介面:
package com.diermeng.designPattern.AbstractFactory; /* * 所有食物的介面 */ public interface Food { /* * 擷取食物的方法 */ public void get(); } |
建立一個麥當勞總店的介面:
package com.diermeng.designPattern.AbstractFactory; /* * 麥當勞總店 */ public interface FoodFactory { //執行個體化漢堡 public Food getHamburg(); //執行個體化雞翅 public Food getChickenWing(); } |
建立漢堡的抽象基類
package com.diermeng.designPattern.AbstractFactory; /* * 漢堡的抽象父類 */ public abstract class Hamburg implements Food{ /* * 擷取漢堡的方法 */ public abstract void get(); } |
建立雞翅的抽象基類
package com.diermeng.designPattern.AbstractFactory; /* * 雞翅的抽象類別 */ public abstract class ChickenWing implements Food{ /* * 擷取雞翅的方法 */ public abstract void get(); } |
建立中心商業街南部的麥當勞分店
package com.diermeng.designPattern.AbstractFactory.impl; import com.diermeng.designPattern.AbstractFactory.Food; import com.diermeng.designPattern.AbstractFactory.FoodFactory; /* * 中心商業街南邊的麥當勞分店 */ public class SouthMacDonald implements FoodFactory { /* * 擷取漢堡 * @see com.diermeng.designPattern.AbstractFactory.FoodFactory#getHamburg() */ public Food getHamburg() { return new SouthMacDonaldHamburg(); } /* * 擷取雞翅 * @see com.diermeng.designPattern.AbstractFactory.FoodFactory#getChickenWing() */ public Food getChickenWing() { return new SouthMacDonaldChickenWing(); } } |
建立華聯那邊麥當勞分店
package com.diermeng.designPattern.AbstractFactory.impl; import com.diermeng.designPattern.AbstractFactory.Food; import com.diermeng.designPattern.AbstractFactory.FoodFactory; /* * 麥當勞的華聯分店 */ public class HualianMacDonald implements FoodFactory { /* * 擷取漢堡 * @see com.diermeng.designPattern.AbstractFactory.FoodFactory#getHamburg() */ public Food getHamburg() { return new HualianMacDonaldHamburg(); } /* * 擷取雞翅 * @see com.diermeng.designPattern.AbstractFactory.FoodFactory#getChickenWing() */ public Food getChickenWing() { return new HualianMacDonaldChickenWing(); } } |
建立中心商業街南邊的麥當勞的漢堡:
package com.diermeng.designPattern.AbstractFactory.impl; import com.diermeng.designPattern.AbstractFactory.Hamburg; /* * 中心商業街南邊的的麥當勞分店的漢堡 */ public class SouthMacDonaldHamburg extends Hamburg { /* * 擷取漢堡 * @see com.diermeng.designPattern.AbstractFactory.Hamburg#get() */ public void get() { System.out.println("擷取中心商業街南邊的的麥當勞分店的漢堡"); } } |
建立華聯那邊的麥當勞的漢堡:
package com.diermeng.designPattern.AbstractFactory.impl; import com.diermeng.designPattern.AbstractFactory.Hamburg; /* * 華聯那邊的麥當勞分店的漢堡 */ public class HualianMacDonaldHamburg extends Hamburg { /* * 擷取漢堡 * @see com.diermeng.designPattern.AbstractFactory.Hamburg#get() */ public void get() { System.out.println("擷取華聯那邊的麥當勞分店的漢堡"); } } |
建立中心商業街南邊的麥當勞雞翅
package com.diermeng.designPattern.AbstractFactory.impl; import com.diermeng.designPattern.AbstractFactory.ChickenWing; /* * 中心商業街南邊的的麥當勞分店的雞翅 */ public class SouthMacDonaldChickenWing extends ChickenWing { /* * 擷取雞翅 * @see com.diermeng.designPattern.AbstractFactory.ChickenWing#get() */ public void get() { System.out.println("擷取中心商業街南邊的的麥當勞分店的雞翅"); } } |
建立華聯那邊的麥當勞的雞翅
package com.diermeng.designPattern.AbstractFactory.impl; import com.diermeng.designPattern.AbstractFactory.ChickenWing; /* * 華聯那邊的麥當勞分店的雞翅 */ public class HualianMacDonaldChickenWing extends ChickenWing { /* * 擷取雞翅 * @see com.diermeng.designPattern.AbstractFactory.ChickenWing#get() */ public void get() { System.out.println("擷取華聯那邊的麥當勞分店的雞翅"); } } |
最後我們建立測試用戶端:
package com.diermeng.designPattern.AbstractFactory.client; import com.diermeng.designPattern.AbstractFactory.Food; import com.diermeng.designPattern.AbstractFactory.FoodFactory; import com.diermeng.designPattern.AbstractFactory.impl.HualianMacDonald; import com.diermeng.designPattern.AbstractFactory.impl.SouthMacDonald; /* * 測試用戶端 */ public class AbstractFactoryTest { public static void main(String[] args) { //聲明並執行個體化中心商業街南邊的的麥當勞分店 FoodFactory southMacDonald= new SouthMacDonald(); //擷取中心商業街南邊的的麥當勞分店的漢堡 Food southMacDonaldHamburg = southMacDonald.getHamburg(); southMacDonaldHamburg.get(); //擷取中心商業街南邊的的麥當勞分店的雞翅 Food southMacDonaldChickenWing = southMacDonald.getChickenWing(); southMacDonaldChickenWing.get(); //聲明並執行個體化華聯那邊的麥當勞分店 FoodFactory hualianMacDonald = new HualianMacDonald(); //擷取華聯那邊的麥當勞分店的漢堡 Food hualianMacDonaldHamburg =hualianMacDonald.getHamburg(); hualianMacDonaldHamburg.get(); //擷取華聯那邊的麥當勞分店的雞翅 Food hualianMacDonaldChickenWing = hualianMacDonald.getChickenWing(); hualianMacDonaldChickenWing.get(); } } |
輸出的結果如下:
擷取中心商業街南邊的的麥當勞分店的漢堡 擷取中心商業街南邊的的麥當勞分店的雞翅 擷取華聯那邊的麥當勞分店的漢堡 擷取華聯那邊的麥當勞分店的雞翅 |
抽象原廠模式的優缺點分析:
優點:用戶端不再負責對象的具體建立,而是把這個責任交給了具體的工廠類,用戶端之負責對對象的調用。當具有產品家族性質的產品被涉及到一個工廠類中後,對用戶端而言是非常友好的,更重要的是如果想要更換為另外一產品家族,所要做的只是需要增加相應的產品家族成員和增加一個具體的產品工廠而已。
缺點:當有新的產品加入的時候,也就是當產品的結構發生改變時,修要修改抽象工廠類的設計,這就導致了必須修改所有的具體工廠類,導致很客觀的工作量的增加。
抽象原廠模式的實際應用簡介:
抽象原廠模式是針對多個產品系列的建立的問題,這在持久化層的設計很實現中有很大的指導意義。由於Java的跨平台性,一般而言,持久化層都要考慮到都腫資料庫的問題,例如MySQL、Oracle等,每一個資料庫就相當於一個產品系列,持久化層必須設計好好不同產品系列的共同介面,這樣才便於使用者操作資料庫,同時也有利於資料庫的移植。大名鼎鼎的Hibernate就很好的借鑒了抽象原廠模式的設計方法。
溫馨提示:
抽象原廠模式考慮的是不同產品系列的建立的問題,並非能到處使用。另外在新增加產品的時候,需要改變抽象工廠的設計,這會導致很大的工作量,所以在規劃之初必須考慮好產品的結構,力求降低參加產品的可能性,是抽象工廠比較穩定。
注意:該文檔參考和使用了網路上的免費開放的圖片和內容,並以免費開放的方式發布,希望為移動互連網和智能手機時代貢獻綿薄之力!可以隨意轉載,但不得使用該文檔謀利。