本文是设计模式系列文章的第三部分,继简单工厂模式和工厂方法模式之后,详细介绍了抽象工厂模式的概念、使用场景、定义、实现以及可能遇到的问题。如果还没有阅读前两部分,建议先阅读它们,然后再继续阅读本文。
抽象工厂模式是设计模式中创建型模式的一种,来源于四人帮(Gang of Four, GoF)的著作。以下是从GoF书中摘录的抽象工厂模式的定义: “提供一个创建一系列相关或依赖对象的接口,而不需要指定它们的具体类。” 将在“理解定义与示例”部分详细解释这个定义。
当需要创建不同类型的相关对象(一组/集合)时,抽象工厂模式是一个不错的选择。它提供了不同类型的工厂。每个工厂将创建特定类型的相关对象。这就是为什么有时称抽象工厂模式为工厂的工厂。简单工厂模式和工厂方法模式只提供一种类型的对象(在示例中,所有对象都是IFan类型)。 注意:如果需要,抽象工厂模式可以与工厂方法模式一起使用。
现在,除了风扇之外,如果还需要创建更多的电器设备,如荧光灯或开关,将选择抽象工厂。为了更清楚地说明,让扩展一个场景,其中需要创建不同类型相关对象的组(电器设备组下的对象)。将继续使用在本系列文章第二部分中采取的类似示例。
让通过上述场景来理解抽象工厂模式的定义。首先创建上述场景的设计图,并尝试将定义与此场景关联起来。以下是显示实现上述场景所需实体的设计图。
在上述图表中,IElectricalFactory为客户端提供了创建相关或依赖对象系列的接口。这里有两个具体的实现类——IndianElectricalFactory和USElectricalFactory。这两个类分别制造了两种不同类型的相关对象系列——风扇和荧光灯。IndianFan和IndianTubelight属于IndianElectricalFactory系列。USTubelight和USFan类属于USElectricalFactory系列。
以下是上述场景的逐步实现:
// 创建两个接口IFan和ITubelight
interface IFan {
void SwitchOn();
}
interface ITubelight { }
// 创建两个具体类,实现IFan和ITubelight
class IndianFan : IFan { }
class IndianTubelight : ITubelight { }
// 创建IElectricalFactory接口,这是实际的抽象工厂
interface IElectricalFactory {
IFan GetFan();
ITubelight GetTubeLight();
}
// 创建IndianElectricalFactory类,继承自IElectricalFactory接口
class IndianElectricalFactory : IElectricalFactory {
public IFan GetFan() {
return new IndianFan();
}
public ITubelight GetTubeLight() {
return new IndianTubelight();
}
}
// 客户端如何创建它们
static void Main(string[] args) {
IElectricalFactory electricalFactory = new IndianElectricalFactory();
IFan fan = electricalFactory.GetFan();
fan.SwitchOn();
Console.ReadKey();
}
正如在上一部分讨论的,公司希望在美国设立新的电器公司,公司名称将为USElectricalFactory。在同一个应用程序中,将添加两个新类USFan和USTubelight,实现所需的接口。IFan和ITubeLight接口的实现将根据美国电器设备标准进行。
// 创建USFan和USTubelight类
class USFan : IFan { }
class USTubelight : ITubelight { }
// 最后创建USElectricalFactory类,继承自IElectricalFactory
class USElectricalFactory : IElectricalFactory {
public IFan GetFan() {
return new USFan();
}
public ITubelight GetTubeLight() {
return new USTubelight();
}
}
现在,如果客户端想要获取美国电器设备,只需在客户端代码中做一个更改,如下所示:
// IElectricalFactory electricalFactory = new IndianElectricalFactory();
IElectricalFactory electricalFactory = new USElectricalFactory();