抽象工厂(Abstract Factory)角色:担任这个角色的是工厂方法模式的核心,它是与应用系统商业逻辑无关的。
具体工厂(Concrete Factory)角色:这个角色直接在客户端的调用下创建产品的实例。这个角色含有选择合适的产品对象的逻辑,而这个逻辑是与应用系统的商业逻辑紧密相关的。
抽象产品(Abstract Product)角色:担任这个角色的类是工厂方法模式所创建的对象的父类,或它们共同拥有的接口。
具体产品(Concrete Product)角色:抽象工厂模式所创建的任何产品对象都是某一个具体产品类的实例。这是客户端最终需要的东西,其内部一定充满了应用系统的商业逻辑
该程序演示了抽象工厂的结构,本身不具有任何实际价值。
//
Abstract Factory pattern -- Structural example
using System;
// "AbstractFactory"
abstract class AbstractFactory
... {
// Methods
abstract public AbstractProductA CreateProductA();
abstract public AbstractProductB CreateProductB();
}
// "ConcreteFactory1"
class ConcreteFactory1 : AbstractFactory
... {
// Methods
override public AbstractProductA CreateProductA()
...{
return new ProductA1();
}
override public AbstractProductB CreateProductB()
...{
return new ProductB1();
}
}
// "ConcreteFactory2"
class ConcreteFactory2 : AbstractFactory
... {
// Methods
override public AbstractProductA CreateProductA()
...{
return new ProductA2();
}
override public AbstractProductB CreateProductB()
...{
return new ProductB2();
}
}
// "AbstractProductA"
abstract class AbstractProductA
... {
}
// "AbstractProductB"
abstract class AbstractProductB
... {
// Methods
abstract public void Interact(AbstractProductA a);
}
// "ProductA1"
class ProductA1 : AbstractProductA
... {
}
// "ProductB1"
class ProductB1 : AbstractProductB
... {
// Methods
override public void Interact(AbstractProductA a)
...{
Console.WriteLine(this + " interacts with " + a);
}
}
// "ProductA2"
class ProductA2 : AbstractProductA
... {
}
// "ProductB2"
class ProductB2 : AbstractProductB
... {
// Methods
override public void Interact(AbstractProductA a)
...{
Console.WriteLine(this + " interacts with " + a);
}
}
// "Client" - the interaction environment of the products
class Environment
... {
// Fields
private AbstractProductA AbstractProductA;
private AbstractProductB AbstractProductB;
// Constructors
public Environment(AbstractFactory factory)
...{
AbstractProductB = factory.CreateProductB();
AbstractProductA = factory.CreateProductA();
}
// Methods
public void Run()
...{
AbstractProductB.Interact(AbstractProductA);
}
}
/**/ /**/
/**/ /// <summary>
/// ClientApp test environment
/// </summary>
class ClientApp
... {
public static void Main(string[] args)
...{
AbstractFactory factory1 = new ConcreteFactory1();
Environment e1 = new Environment(factory1);
e1.Run();
AbstractFactory factory2 = new ConcreteFactory2();
Environment e2 = new Environment(factory2);
e2.Run();
}
}
using System;
// "AbstractFactory"
abstract class AbstractFactory
... {
// Methods
abstract public AbstractProductA CreateProductA();
abstract public AbstractProductB CreateProductB();
}
// "ConcreteFactory1"
class ConcreteFactory1 : AbstractFactory
... {
// Methods
override public AbstractProductA CreateProductA()
...{
return new ProductA1();
}
override public AbstractProductB CreateProductB()
...{
return new ProductB1();
}
}
// "ConcreteFactory2"
class ConcreteFactory2 : AbstractFactory
... {
// Methods
override public AbstractProductA CreateProductA()
...{
return new ProductA2();
}
override public AbstractProductB CreateProductB()
...{
return new ProductB2();
}
}
// "AbstractProductA"
abstract class AbstractProductA
... {
}
// "AbstractProductB"
abstract class AbstractProductB
... {
// Methods
abstract public void Interact(AbstractProductA a);
}
// "ProductA1"
class ProductA1 : AbstractProductA
... {
}
// "ProductB1"
class ProductB1 : AbstractProductB
... {
// Methods
override public void Interact(AbstractProductA a)
...{
Console.WriteLine(this + " interacts with " + a);
}
}
// "ProductA2"
class ProductA2 : AbstractProductA
... {
}
// "ProductB2"
class ProductB2 : AbstractProductB
... {
// Methods
override public void Interact(AbstractProductA a)
...{
Console.WriteLine(this + " interacts with " + a);
}
}
// "Client" - the interaction environment of the products
class Environment
... {
// Fields
private AbstractProductA AbstractProductA;
private AbstractProductB AbstractProductB;
// Constructors
public Environment(AbstractFactory factory)
...{
AbstractProductB = factory.CreateProductB();
AbstractProductA = factory.CreateProductA();
}
// Methods
public void Run()
...{
AbstractProductB.Interact(AbstractProductA);
}
}
/**/ /**/
/**/ /// <summary>
/// ClientApp test environment
/// </summary>
class ClientApp
... {
public static void Main(string[] args)
...{
AbstractFactory factory1 = new ConcreteFactory1();
Environment e1 = new Environment(factory1);
e1.Run();
AbstractFactory factory2 = new ConcreteFactory2();
Environment e2 = new Environment(factory2);
e2.Run();
}
}
在以下情况下应当考虑使用抽象工厂模式:
- 一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有形态的工厂模式都是重要的。
- 这个系统有多于一个的产品族,而系统只消费其中某一产品族。
- 同属于同一个产品族的产品是在一起使用的,这一约束必须在系统的设计中体现出来。
- 系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于实现。
"开放-封闭"原则
"开放-封闭"原则要求系统对扩展开放,对修改封闭。通过扩展达到增强其功能的目的。对于涉及到多个产品族与多个产品等级结构的系统,其功能增强包括两方面:
增加产品族:Abstract Factory很好的支持了"开放-封闭"原则。
增加新产品的等级结构:需要修改所有的工厂角色,没有很好支持"开放-封闭"原则。
综合起来,抽象工厂模式以一种倾斜的方式支持增加新的产品,它为新产品族的增加提供方便,而不能为新的产品等级结构的增加提供这样的方便。