设计模式(二)—— 工厂方法

模式简介


工厂方法模式(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 = "|                              \n";
        flowChart += "|                                    \n";
        flowChart += "|                -------             \n";
        flowChart += "|               | START |            \n";
        flowChart += "|                -------             \n";
        flowChart += "|                   |                \n";
        flowChart += "|                -------             \n";
        flowChart += "|               |  ...  |            \n";
        flowChart += "|                -------             \n";
        flowChart += "|                   |                \n";
        flowChart += "|                -------             \n";
        flowChart += "|               |  END  |            \n";
        flowChart += "|                -------             \n";
        flowChart += "|                                    \n";
        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();
}

程序输出

优缺点


优点

  • 客户端只需要关心所需产品对应的工厂,无须关心产品创建的细节,甚至无须知道具体产品类的类名。
  • 在系统中加入新产品时,无须修改已经完成的类,只要添加具体的产品和工厂就可以了。

缺点

  • 添加新产品时,不仅需要添加具体的产品类,还要提供与之对应的具体工厂类,系统中类的数量成对增长,在一定程度上增加了系统的复杂度。

适用场景


  • 当一个类不知道它所必须创建的对象的类的时候

  • 当一个类希望由它的子类来指定它所创建的对象的时候

  • 当类将创建对象的职责委托给多个帮助子类中的某一个,并且希望将哪一个帮助子类时代理者这一信息局部化的时候

posted @ 2018-04-24 20:15  Answer.Geng  阅读(442)  评论(0编辑  收藏  举报