抽象工厂模式(Abstract Factory)
关键词:系列
问题:多个类型中以系列化的方式创建对象.
意图: 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类
适用性
优点:
在工厂方法模式中,工厂方法用来创建客户所需要的产品,同时还向客户隐藏了哪种具体产品类将被实例化这一细节,用户只需要关心所需产品对应的工厂,无须关心创建细节,甚至无须知道具体产品类的类名。
基于工厂角色和产品角色的多态性设计是工厂方法模式的关键。它能够使工厂可以自主确定创建何种产品对象,而如何创建这个对象的细节则完全封装在具体工厂内部。
工厂方法模式之所以又被称为多态工厂模式,是因为所有的具体工厂类都具有同一抽象父类。
使用工厂方法模式的另一个优点是在系统中加入新产品时,无须修改抽象工厂和抽象产品提供的接口,无须修改客户端,也无须修改其他的具体工厂和具体产品,而只要添加一个具体工厂和具体产品就可以了。这样,系统的可扩展性也就变得非常好,完全符合“开闭原则”。
缺点:
在添加新产品时,需要编写新的具体产品类,而且还要提供与之对应的具体工厂类,系统中类的个数将成对增加,在一定程度上增加了系统的复杂度,有更多的类需要编译和运行,会给系统带来一些额外的开销。
由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到DOM、反射等技术,增加了系统的实现难度。
解决方案【步骤】
问题描述:
在中国工厂只能创建中国的坦克,中国的战斗机。
在美国工厂只能创建美国的坦克,美国的战斗机。
实现类图
本例以中文命名类名,方法名,是为了便于学习理解,实际工作并不建议编程以中文命名。
抽象工厂
public abstract class 抽象工厂
{
public string 国家;
abstract public 坦克 创建坦克();
abstract public 战斗机 创建战斗机();
}
中国工厂
public class 中国工厂 : 抽象工厂
{
public override 坦克 创建坦克()
{
return new 中国坦克();
}
public override 战斗机 创建战斗机()
{
return new 中国战斗机();
}
}
美国工厂
public class 美国工厂 : 抽象工厂
{
public override 坦克 创建坦克()
{
return new 美国坦克();
}
public override 战斗机 创建战斗机()
{
return new 美国战斗机();
}
}
坦克
public abstract class 坦克
{
public abstract void GetCountry();
}
中国坦克
using System;
public class 中国坦克 : 坦克
{
public override void GetCountry()
{
Console.WriteLine("我是中国坦克");
}
}
美国坦克
using System;
public class 美国坦克 : 坦克
{
public override void GetCountry()
{
Console.WriteLine("我是美国坦克");
}
}
战斗机
public abstract class 战斗机{
}
中国战斗机
public class 中国战斗机 : 战斗机{
}
美国战斗机
public class 美国战斗机 : 战斗机{
}
测试
using System;
class Program
{
static void Main(string[] args)
{
抽象工厂 factory = new 中国工厂();
factory.国家 = "中国";
坦克 tank = factory.创建坦克();
战斗机 fly = factory.创建战斗机();
Console.WriteLine(factory.国家);
Console.WriteLine(tank);
Console.WriteLine(fly);
tank.GetCountry();
Console.ReadLine();
}
}