1.常規的對象建立方法:
// 建立一個Road 對象
Road road=new Road();
new的問題:
– 實現依賴,不能應對“具體執行個體化類型”的變化。
2.原廠模式的緣起
• 變化點在“對象建立”,因此就封裝“對象建立”
• 面向介面編程——依賴介面,而非依賴實現
最簡單的解決方案:
class RoadFactory {
public static Road CreateRoad()
{
return new Road();
}
}
// 在其他類裡面建立一個Road 對象
Road road=
roadFactory.CreateRoad();
3.建立一系列相互依賴的對象
假設一個遊戲開發情境:
我們需要構造“道路”、
“房屋”、“地道”、“叢
林”……等等對象
普通的靜態工廠:
class FacilityFactory {
public static Road CreateRoad()
{
return new Road();
}
public static Building
CreateBuilding ()
{
return new Building();
}
public static Tunnel
CreateTunnel ()
{
return new Tunnel();
}
public static Jungle
CreateJungle()
{
return new Jungle
}
}
簡單工廠的問題:
– 不能應對“不同系列對象”的變化。比如有不同風格的遊
戲情境——對應不同風格的道路、房屋、地道……
4.Abstract Factory
動機:在軟體系統中,經常面臨著“一系列相互依賴的對象”的建立
工作;同時,由於需求的變化,往往存在更多系列對象的
建立工作。
意圖:提供一個介面,讓該介面負責建立一系列“相關或者
相互依賴的對象”,無需指定它們具體的類。
結構:
//抽象類別
public abstract class Road()
{}
public abstract class Building()
{}
public abstract class Tunnel()
{}
public abstract class Jungle()
{}
//抽象工廠類
abstract class FacilitiesFactory
{
public abstract Road CreateRoad();
public abstract Building CreateBuilding();
public abstract Tunnel CreateTunnel();
public abstract Jungle CreateJungle();
}
//客戶程式
客戶程式依賴於上面的抽象類別和抽象工廠,不依賴於具體的實現
class GameManager
{
Road road;
Building building;
Tunnel tunnel;
Jungle jungle;
FacilitiesFactory facilitiesFacotry;
public GameManager(FacilitiesFactory facilitiesFactory)
{this.facilitiesFactory=facilitiesFactory;}
public void BuildGameFacilities()
{
road = facilitiesFactory.CreateRoad();
building = facilitiesFactory.CreateBuilding();
tunnel = facilitiesFactory.CreateTunnel();
jungle = facilitiesFactory.CreateJungle();
}
public void Play()
{
road.AAA();
building.BBB(road);
tunnel.CCC();
jungle.DDD(tunnel);
}
}
抽象類別的具體實現:
public class ModernRoad():Road
{}
public class ModernBuilding():Building
{}
public class ModernTunnel():Tunnel
{}
public class ModernJungle():Jungle
{}
抽象工廠的具體實作類別
class ModernFacilitiesFactory:FacilitiesFactory
{
public overried Road CreateRoad( return ModernRoad(););
public overried Building CreateBuilding(return ModernBuilding(););
public overried Tunnel CreateTunnel(return ModernTunnel(););
public overried Jungle CreateJungle(return ModernJungle(););
}
這樣就建立了一個現代風格的設施,傳入客戶程式的建構函式。如果要建立古典風格的設施,只需要提供古典設施的實現(抽象類別和抽象工廠的實現),只需要將下面這個類的GameManager參數改為古典風格抽象工廠實作類別的執行個體new ClassicFacilitiesFactory()或者將這個參數寫在設定檔裡面,我們只需要修改設定檔就可以在遊戲中實現古典風格的遊戲情境,而客戶程式不需要一點的修改。
//調用客戶程式的類
class App
{
public static void Main()
{
GameManger g= new GameManger( new ModernFacilitiesFactory());
g.BuildGameFacilities();
g.Run();
}
}
Abstract Factory模式的幾個要點:
如果沒有應對“多系列對象構建”的需求變化,則沒有必要
使用Abstract Factory模式,這時候使用簡單的靜態工廠
完全可以。
• “系列對象”指的是這些對象之間有相互依賴、或作用的關
系,例如遊戲開發情境中的“道路”與“房屋”的依賴,“道路”
與“地道”的依賴。
• Abstract Factory模式主要在於應對“新系列”的需求變動。
其缺點在於難以應對“新對象”的需求變動。
• Abstract Factory模式經常和Factory Method模式共同組合
來應對“對象建立”的需求變化。