抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。
为了方便引进抽象工厂模式,引进一个新概念:产品族(Product Family)。所谓产品族,是指位于不同产品等级结构,功能相关联的产品组成的家族。如图:
图中一共有四个产品族,分布于三个不同的产品等级结构中。只要指明一个产品所处的产品族以及它所属的等级结构,就可以唯一的确定这个产品。
所谓的抽象工厂是指一个工厂等级结构可以创建出分属于不同产品等级结构的一个产品族中的所有对象。
简单例子
public abstract class Road
{
}
// 建筑的抽象类(也可实现为接口)
public abstract class Building
{
}
// 地道的抽象类(也可实现为接口)
public abstract class Tunnel
{
}
// 丛林抽象类(也可实现为接口)
public abstract class Jungle
{
}
// 设施工厂抽象类
public abstract class FacilitiesFactory
{
public abstract Road CreateRoad();
public abstract Building CreateBuilding();
public abstract Tunnel CreateTunnel();
public abstract Jungle CreateJungle();
}
// 现代风格的路
public class ModernRoad : Road
{
}
// 现代风格的建筑
public class ModernBuilding : Building
{
}
// 现代风格的地道
public class ModernTunnel : Tunnel
{
}
// 现代风格的丛林
public class ModernJungle : Jungle
{
}
// 具体的设施工厂
public class ModernFacilitiesFactory : FacilitiesFactory
{
public override Road CreateRoad()
{
return new ModernRoad();
}
public override Building CreateBuilding()
{
return new ModernBuilding();
}
public override Tunnel CreateTunnel()
{
return new ModernTunnel();
}
public override Jungle CreateJungle()
{
return new ModernJungle();
}
}
// 管理程序(注意他对具体的类没有任何的依赖,全部依赖抽象的东西,完全利用多态的东西,使它变的非常的稳定)
public class GameManager
{
private FacilitiesFactory facilitiesFactory;
private Road road;
private Building building;
private Tunnel tunnel;
private Jungle jungle;
// 构造函数
public GameManager(FacilitiesFactory ff)
{
this .facilitiesFactory = ff;
}
// 创建设施
public void BulidGameFacilities()
{
road = facilitiesFactory.CreateRoad();
building = facilitiesFactory.CreateBuilding();
tunnel = facilitiesFactory.CreateTunnel();
jungle = facilitiesFactory.CreateJungle();
}
// 运行程序
public void Run()
{
road.AAA();
building.BBB(road);
tunnel.CCC();
jungle.DDD(tunnel);
}
}
// 客户程序
public class App
{
public static void Main()
{
// 当要换一种风格的游戏场景,只要参数改变即可,非常的隔离变化点
GameManager g = new GameManager( new ModernFacilitiesFactory());
g.BulidGameFacilities();
g.Run();
}
}
在以下情况下应当考虑使用抽象工厂模式:
•一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有形态的工厂模式都是重要的。
•这个系统有多于一个的产品族,而系统只消费其中某一产品族。
•同属于同一个产品族的产品是在一起使用的,这一约束必须在系统的设计中体现出来。
•系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于实现。
要点
• 如果没有应对“多系列对象构建”的需求变化,则没有必要使用Abstract Factory模式,这时候使用简单的静态工厂完全可以。
•“ 系列对象”指的是这些对象之间有相互依赖、或作用的关系,例如游戏开发场景中的“道路”与“房屋”的依赖,“道路”
与“地道”的依赖。
• Abstract Factory模式主要在于应对“新系列”的需求变动。其缺点在于难以应对“新对象”的需求变动。
• Abstract Factory模式经常和Factory Method模式共同组合来应对“对象创建”的需求变化。
综合起来,抽象工厂模式以一种倾斜的方式支持增加新的产品,它为新产品族的增加提供方便,而不能为新的产品等级结构的增加提供这样的方便。