el-tree,很噁心的樹,就從預設展開節點開始吧
轉自:《Java 設計模式》2009年( 耿祥義 張躍平 著)
一,概括
抽象工廠模式(別名:配套)
提供一個建立一系列或相互依賴物件的介面,而無需指定他們具體的類
二,引入
設計某些系統是可能需要為使用者提供一系列相關的物件,但系統不希望使用者直接使用 new運算子 例項化這些物件,而是應由系統控制這些物件的建立。否則使用者不僅要知道用哪些類來建立物件,而且還必須清楚這些物件之間是怎麼相關的,使得使用者的程式碼與這些類形成耦合,不利於維護。
比如:商家要去工廠採購衣服褲子,這些商家自然不能自己生產衣服(直接使用 new運算子 例項化這些物件,用哪些類來建立物件).這些商家只能來到特定的工廠,他們自然會提供給你提供他們品牌的衣服。其中這些工廠是有生產配套的衣服和褲子的,商家也無需事先了解哪些衣服和褲子是一套的(物件之間是怎麼相關的),工廠直接就提供給你一整套的衣物,這些衣物配套生產,這些商家也無法單獨購買。商家只需要對工廠提供給你的樣品衣物中做出選擇,是否購買。
三,程式碼與類圖
衣服有兩種衣服,江牌風衣和鳥牌襯衫;褲子有兩種褲子,江牌牛仔褲和鳥牌裙子;工廠有兩座,一個是江牌的工廠。一個是鳥牌的工廠。
package MM; /************************* Clothes *************************/ abstract class Clothes { abstract public int getChestSize(); abstract public int getHeight(); abstract public String getName(); } class WindCoat extends Clothes { public int getChestSize() { return 90; } public int getHeight() { return 175; } public String getName() { return "江牌風衣"; } } class Shirt extends Clothes { public int getChestSize() { return 90; } public int getHeight() { return 170; } public String getName() { return "鳥牌襯衫"; } } /************************* Pants *************************/ abstract class Pants { abstract public int getWaistSize(); abstract public int getHeight(); abstract public String getName(); } class Jeans extends Pants { public int getWaistSize() { return 75; } public int getHeight() { return 175; } public String getName() { return "江牌牛仔褲"; } } class Skirt extends Pants { public int getWaistSize() { return 62; } public int getHeight() { return 170; } public String getName() { return "鳥牌裙子"; } } /************************* Factory *************************/ abstract class Factory { public Factory() { System.out.printf("生產了一套衣物:\n"); System.out.printf(createClothes().getName() + ": \n"); System.out.printf("*胸圍:" + createClothes().getChestSize() + "\n"); System.out.printf("*身高:" + createPants().getHeight() + "\n"); System.out.printf(createPants().getName() + ": \n"); System.out.printf("*腰圍:" + createPants().getWaistSize() + "\n"); System.out.printf("*身高:" + createPants().getHeight() + "\n"); System.out.printf("\n"); } abstract public Clothes createClothes(); abstract public Pants createPants(); } class JiangFactory extends Factory { public Clothes createClothes() { return new WindCoat(); } public Pants createPants() { return new Jeans(); } } class NiaoFactory extends Factory { public Clothes createClothes() { return new Shirt(); } public Pants createPants() { return new Skirt(); } } public class M { public static void main(String L[]) { Clothes c; Pants p; Factory f; f = new JiangFactory(); c = f.createClothes(); p = f.createPants(); f = new NiaoFactory(); c = f.createClothes(); p = f.createPants(); } }
類圖:
(注: 由於找不到合適的箭頭,這箭頭就畫的不標準了)
四,工廠方法模式的結構
① 抽象產品(Product): Clothes類 和 Pants類
② 具體產品(ConcreteProduct):WindCoat類 和 Shirt類 和 Jeans類 和 Skirt類
③ 抽象工廠(Creator): Factory類
④ 具體工廠(ConcreteCreator): JiangFactory1類 和 NiaoFactory類
五,抽象工廠模式的優缺點
優點:
① 抽象工廠模式可以為使用者建立一系列相關的物件,使使用者和建立這些物件的類脫耦。
② 使用者使用不同的具體工廠就能得到一組相關的物件,可以避免使用者混用不同系列中的物件。
③ 在抽象工廠模式中,可以隨時增加 “具體工廠”,為使用者提供一組相關的物件。
缺點:一旦原有的實體類進行擴充,就無法正常工作,(如在上述例子中,還要給 江牌 的套裝增加一雙襪子,就必須修改抽象工廠的程式碼了)
六,抽象工廠模式的使用場景
① 系統需要為使用者提供多個物件,又希望使用者和建立物件的類脫耦。
②系統需要為使用者提供多個相關的物件,當又不希望使用者決定這些物件是如何關聯的。
③ 系統需要使用者提供一系列物件,使用者只需要知道有這些物件有哪些方法可用,不需要知道這些物件的建立過程。
七,抽象工廠模式的使用
使用者在使用抽象工廠模式時,只和抽象產品,抽象工廠以及具體構工廠打交道,使用者只需瞭解抽象產品有哪些方法,不需要知道有哪些具體產品。
抽象工廠方法模式的關鍵是 在一個介面或抽象類中定義若干個 抽象方法(抽象工廠),這些方法分別返回某個類的子類的例項,該抽象類或介面 讓其 子類或實現該介面的類(具體工廠) 通過重寫這些抽象方法 為使用者提供一系列相關的物件
=========== ========= ======== ======= ===== ==== === == =