设计模式之抽象工厂模式
一、定义
抽象工厂是一种创建型设计模式, 它能创建一系列相关的对象, 而无需指定其具体类。
二、方案
抽象工厂模式建议为系列中的每件产品明确声明接口 (例如椅子、 沙发或咖啡桌)。 然后, 确保所有产品变体都继承这些接口。 例如, 所有风格的椅子都实现 椅子
接口; 所有风格的咖啡桌都实现 咖啡桌
接口, 以此类推。客户端代码可以通过相应的抽象接口调用工厂和产品类。 你无需修改实际客户端代码, 就能更改传递给客户端的工厂类, 也能更改客户端代码接收的产品变体。
三、适合应用场景
- 如果代码需要与多个不同系列的相关产品交互, 但是由于无法提前获取相关信息, 或者出于对未来扩展性的考虑, 你不希望代码基于产品的具体类进行构建, 在这种情况下, 你可以使用抽象工厂。
- 如果你有一个基于一组抽象方法的类, 且其主要功能因此变得不明确, 那么在这种情况下可以考虑使用抽象工厂模式。
四、实现方式
- 以不同的产品类型与产品变体为维度绘制矩阵。
- 为所有产品声明抽象产品接口。 然后让所有具体产品类实现这些接口。
- 声明抽象工厂接口, 并且在接口中为所有抽象产品提供一组构建方法。
- 为每种产品变体实现一个具体工厂类。
- 在应用程序中开发初始化代码。 该代码根据应用程序配置或当前环境, 对特定具体工厂类进行初始化。 然后将该工厂对象传递给所有需要创建产品的类。
- 找出代码中所有对产品构造函数的直接调用, 将其替换为对工厂对象中相应构建方法的调用。
五、优缺点
- 你可以确保同一工厂生成的产品相互匹配。✔
- 你可以避免客户端和具体产品代码的耦合。✔
- 单一职责原则。 你可以将产品生成代码抽取到同一位置, 使得代码易于维护。✔
- 开闭原则。 向应用程序中引入新产品变体时, 你无需修改客户端代码。✔
- 由于采用该模式需要向应用中引入众多接口和类, 代码可能会比之前更加复杂。×
六、代码实例
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DesignModel.FactoryMethod
{
/// <summary>
/// 抽象工厂接口声明一组方法,这些方法返回不同的抽象产品。这些产品被称为一个系列
/// 与高层次的主题或概念相关的。一个家庭的产品是他们通常能够相互合作
/// 一个系列的产品可以有几个变体,但其中一个变体的产品不兼容用别人的产品
/// </summary>
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();
}
}
/// <summary>
/// 产品系列中的每个不同产品都应该有一个基本接口。
/// 产品的所有变体都必须实现此接口。
/// </summary>
public interface IAbstractProductA
{
string UsefulFunctionA();
}
class ConcreteProductA1 : IAbstractProductA
{
public string UsefulFunctionA()
{
return "产品A1的结果";
}
}
class ConcreteProductA2 : IAbstractProductA
{
public string UsefulFunctionA()
{
return "产品A2的结果";
}
}
public interface IAbstractProductB
{
/// <summary>
/// 产品B做自己的事情
/// </summary>
/// <returns></returns>
string UsefulFunctionB();
/// <summary>
/// 但它也可以与产品合作。
/// 抽象工厂确保它生产的所有产品都是有价值的
/// 相同的变体,因此,兼容。
/// </summary>
/// <param name="collaborator"></param>
/// <returns></returns>
string AnotherUsefulFunctionB(IAbstractProductA collaborator);
}
class ConcreteProductB1 : IAbstractProductB
{
public string AnotherUsefulFunctionB(IAbstractProductA collaborator)
{
var result = collaborator.UsefulFunctionA();
return $"这是B1与{result}合作";
}
public string UsefulFunctionB()
{
return "产品B1的结果";
}
}
class ConcreteProductB2 : IAbstractProductB
{
public string AnotherUsefulFunctionB(IAbstractProductA collaborator)
{
var result = collaborator.UsefulFunctionA();
return $"这是B2与{result}合作";
}
public string UsefulFunctionB()
{
return "产品B2的结果";
}
}
}
namespace DesignModel
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("用第一种工厂类型测试相同的客户端代码");
ClientMethod(new ConcreteFactory1());
Console.WriteLine();
Console.WriteLine("用第二种工厂类型测试相同的客户端代码");
ClientMethod(new ConcreteFactory2());
Console.ReadLine();
}
public static void ClientMethod(IAbstractFactory factory)
{
var productA = factory.CreateProductA();
var productB = factory.CreateProductB();
Console.WriteLine(productB.UsefulFunctionB());
Console.WriteLine(productB.AnotherUsefulFunctionB(productA));
}
}
}
B7qOL8.png
网友评论