A Sort Of A Blog
旧游无处不堪寻,无寻处,惟有少年心
设计模式-抽象工厂

抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,它能创建一系列相关的对象,而无需指定其具体类。

解释


抽象工厂模式建议为系列中的每件产品明确声明接口,然后确保所有产品变体都继承这些接口

接下来,我们需要声明抽象工厂,该类中包含系列中所有产品构造方法的接口。

对于系列产品的每个变体,我们都将基于抽象工厂接口创建不同的工厂类,每个工厂类都只能返回特定类别的产品

抽象工厂模式 UML


适用场景


  1. 如果代码需要与多个不同系列的相关产品交互,但是由于无法提前获取相关信息,或者出于对未来扩展性的考虑,你不希望代码基于产品的具体类进行构建,在这种情况下,你可以使用抽象工厂
  2. 如果你有一个基于一组抽象方法的类,且其主要功能因此变得不明确,那么在这种情况下可以考虑使用抽象工厂模式

代码示例


using System;
namespace AbstractFactoryPatternDemo
{
// abstract factory
public interface IAbstractFactory
{
IAbstractProductA CreateProductA();

IAbstractProductB CreateProductB();
}

class ConcreteFactory1 : IAbstractFactory
{
public IAbstractProductA CreateProductA()
{
return new ConcreteProductA1();
}

public IAbstractProductB CreateProductB()
{
return new ConcreteProductB1();
}
}

class ConcreteFactory2 : IAbstractFactory
{
public IAbstractProductA CreateProductA()
{
return new ConcreteProductA2();
}

public IAbstractProductB CreateProductB()
{
return new ConcreteProductB2();
}
}

// abstract product a
public interface IAbstractProductA
{
string UsefulFunctionA();
}

class ConcreteProductA1 : IAbstractProductA
{
public string UsefulFunctionA()
{
return "The result of the product A1.";
}
}

class ConcreteProductA2 : IAbstractProductA
{
public string UsefulFunctionA()
{
return "The result of the product A2.";
}
}

// abstract product b
public interface IAbstractProductB
{
string UsefulFunctionB();

string AnotherUsefulFunctionB(IAbstractProductA collaborator);
}

class ConcreteProductB1 : IAbstractProductB
{
public string UsefulFunctionB()
{
return "The result of the product B1.";
}

public string AnotherUsefulFunctionB(IAbstractProductA collaborator)
{
var result = collaborator.UsefulFunctionA();

return $"The result of the B1 collaborating with the ({result})";
}
}

class ConcreteProductB2 : IAbstractProductB
{
public string UsefulFunctionB()
{
return "The result of the product B2.";
}

public string AnotherUsefulFunctionB(IAbstractProductA collaborator)
{
var result = collaborator.UsefulFunctionA();

return $"The result of the B2 collaborating with the ({result})";
}
}

// client
class Client
{
public void Main()
{

Console.WriteLine("Client: Testing client code with the first factory type...");
ClientMethod(new ConcreteFactory1());
Console.WriteLine();

Console.WriteLine("Client: Testing the same client code with the second factory type...");
ClientMethod(new ConcreteFactory2());
}

public void ClientMethod(IAbstractFactory factory)
{
var productA = factory.CreateProductA();
var productB = factory.CreateProductB();

Console.WriteLine(productB.UsefulFunctionB());
Console.WriteLine(productB.AnotherUsefulFunctionB(productA));
}
}

// program
class Program
{
static void Main(string[] args)
{
new Client().Main();
// output

// Client: Testing client code with the first factory type...
// The result of the product B1.
// The result of the B1 collaborating with the (The result of the product A1.)

// Client: Testing the same client code with the second factory type...
// The result of the product B2.
// The result of the B2 collaborating with the (The result of the product A2.)
}
}
}