模式简介
工厂方法模式(Factory Method Pattern)又被称为工厂模式,也叫虚构造器(Virtual Constructor)模式或多态工厂(Polymorphic Factory)模式,它属于类创建型模式。在工厂方法模式中,工厂父类负责定义一个用于创建产品对象的公共接口,让子类决定实例化具体的产品对象。使产品类的实例化延迟到工厂子类中。
结构分析
UML类图
角色说明
- Product
抽象产品类。定义工厂方法所创建的对象的接口。
- ConcreteProduct
具体产品类。实现Product接口,工厂方法的创建目标。
- Factory
抽象工厂类。声明工厂方法,该方法返回一个Product类型的对象。也可以定义一个工厂方法的缺省实现,它返回一个缺省的ConcreteProduct对象。
- ConcreteFactory
具体工厂类。重定义工厂方法以返回一个ConcreteProduct实例。
示例分析
仍以上一篇(设计模式(一)—— 简单工厂)中图表工具包为例。
考虑一下使用简单工厂模式的设计有什么问题?
当我们添加产品(图表)时,ChartFactory工厂也要做出相应的修改,这就违反了类的开放封闭原则。
使用工厂方法优化该示例
注意两者的差别
工厂方法模式创建了抽象工厂ChartFactory,分别实现了LineChartFactory、BarChartFactory以及PieChartFactory三个具体子类,并在工厂子类中返回相应的Chart实例。
public abstract class ChartFactory
{
public abstract Chart CreateChart();
}
public class LineChartFactory : ChartFactory
{
public override Chart CreateChart()
{
return new LineChart();
}
}
public class BarChartFactory : ChartFactory
{
public override Chart CreateChart()
{
return new BarChart();
}
}
public class PieChartFactory : ChartFactory
{
public override Chart CreateChart()
{
return new PieChart();
}
}
这样,在新增产品(图表)时,我们便不再需要修改已经完成的类,转而增加相应的产品及工厂子类即可。例如,现增加流程图FlowChart。
创建产品类FlowChart
public class FlowChart : Chart
{
public override void Draw()
{
string flowChart = "|
";
flowChart += "|
";
flowChart += "| -------
";
flowChart += "| | START |
";
flowChart += "| -------
";
flowChart += "| |
";
flowChart += "| -------
";
flowChart += "| | ... |
";
flowChart += "| -------
";
flowChart += "| |
";
flowChart += "| -------
";
flowChart += "| | END |
";
flowChart += "| -------
";
flowChart += "|
";
flowChart += "|______________________________________";
Console.WriteLine(flowChart);
}
}
创建相应的工厂类FlowChartFactory
public class FlowChartFactory : ChartFactory
{
public override Chart CreateChart()
{
return new FlowChart();
}
}
客户端调用
static void Main(string[] args)
{
FlowChartFactory factory = new FlowChartFactory();
var flowChart = factory.CreateChart();
flowChart.Draw();
Console.ReadLine();
}
程序输出
优缺点
优点
- 客户端只需要关心所需产品对应的工厂,无须关心产品创建的细节,甚至无须知道具体产品类的类名。
- 在系统中加入新产品时,无须修改已经完成的类,只要添加具体的产品和工厂就可以了。
缺点
- 添加新产品时,不仅需要添加具体的产品类,还要提供与之对应的具体工厂类,系统中类的数量成对增长,在一定程度上增加了系统的复杂度。
适用场景
-
当一个类不知道它所必须创建的对象的类的时候
-
当一个类希望由它的子类来指定它所创建的对象的时候
-
当类将创建对象的职责委托给多个帮助子类中的某一个,并且希望将哪一个帮助子类时代理者这一信息局部化的时候