详解工厂模式

来源:互联网 发布:python量化交易 编辑:程序博客网 时间:2024/06/14 07:27

原文地址:http://blog.csdn.net/lilysara/article/details/66975628

工厂模式

工厂模式是创建模式,主要是为创建对象提供过渡接口 ,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。
工厂模式在《深入浅出设计模式》和《大话设计模式》中分为三类:

  • 简单工厂模式(Simple Factory)
  • 工厂方法模式(Factory Factory)
  • 抽象工厂模式(Abstract Factory)

这三种模式从上到下逐步抽象,并且更具有一般性。
我刚开始看着《大话设计模式》学习,抽象工厂还没看到,所以这一篇就先记一下前两种,后面看到了再更新。。。

简单工厂模式

简单工厂模式又称为静态工厂方法模式,它其实不是23种设计模式之一,只是工厂模式的简单版本(嗯,看名字就知道了)。我的理解,简单地说,它就是用一个单独的类来进行创建实例这个过程。

简单工厂模式的组成有:

  • 工厂类角色,它是这个模式的核心,包含一定的判断逻辑。
  • 抽象产品角色,它是具体产品所继承的父类或实现的接口。
  • 具体产品角色,这才是使用模式要创建的具体实例的类。

类图如下:
这里写图片描述

借《大话设计模式》中的例子,展示一下模式的应用。
语言:C#
编译环境:Mac MonoDevelop
要求:实现一个计算器的功能。
计算器有不同的运算符(+、-、*、/),这些运算符都有一个共同的特点:使用两个操作数,然后得出运算结果,因此我们可以写出运算基类。

public class Operation{    private double _numberA = 0;    private double _numberB = 0;    public double NumberA    {        get { return _numberA; }        set { _numberA = value; }    }    public double NumberB    {        get { return _numberB; }        set { _numberB = value; }    }    public virtual double GetResult()    {        double result = 0;        return result;    }}

接下来,写出继承自运算类的加法类、减法类等。

class OperationAdd : Operation {    public override double GetResult()    {        double result = 0;        result = NumberA + NumberB;        return result;    }}class OperationSub : Operation{    public override double GetResult()    {        double result = 0;        result = NumberA - NumberB;        return result;    }}

乘法类、除法类同理可以实现。
接下来是关键的工厂类,根据传入的参数的不同,动态地决定实例化哪个类。

public class OperationFactory{    public static Operation createOperate(string operate)    {        Operation oper = null;        switch (operate) {        case "+":            oper = new OperationAdd ();            break;        case "-":            oper = new OperationSub ();            break;        }        return oper;    }}

最后是客户端的实现。

Operation oper;oper = OperationFactory.createOperate ("+");oper.NumberA = 1;oper.NumberB = 2;double result = oper.GetResult ();Console.WriteLine ("result = " + result.ToString());

这样就完成了简单工厂模式,如果后面要增加其他运算,比如乘方、正弦等,只需要增加相应的运算子类,然后在工厂类里增加判断即可。

写到这里,大家大概可以看出简单工厂的优缺点了。
优点:
工厂类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的责任,而仅仅”消费”产品。简单工厂模式通过这种做法实现了对责任的分割。
缺点:
1) 当产品有复杂的多层等级结构时,工厂类只有自己,以不变应万变,就是模式的缺点。因为工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。
2) 系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,有可能造成工厂逻辑过于复杂,而且违背了开闭原则。
3) 简单工厂模式通常使用静态工厂方法,这使得无法由子类继承,造成工厂角色无法形成基于继承的等级结构。
工厂方法模式就可以很好地解决这种扩展的局限性。

工厂方法模式

工厂方法模式,定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
工厂方法模式的结构:

  • 抽象工厂角色 ,这是工厂方法模式的核心,它与应用程序无关,是具体工厂角色必须实现的接口或必须继承的父类。
  • 具体工厂角色,具体实现创建对象的过程。
  • 抽象产品角色,具体产品继承的父类或实现的接口。
  • 具体产品角色,具体工厂所创建的对象就是这个。

类图如下:
这里写图片描述

接下来,看看如何用工厂方法模式改造上面的例子。

// 这是一个工厂类的接口interface IFactory{    Operation CreateOperation();}// 以下是各个工厂子类,需要实现工厂接口class AddFactory : IFactory {    // 在不同的子类中返回不同的产品实例    public Operation CreateOperation(){        return new OperationAdd();    }}class SubFactory : IFactory {    public Operation CreateOperation(){        return new OperationSub();    }}

接下来是客户端的实现:

IFactory operFactory = new AddFactory();Operation oper = operFactory.CreateOperation ();oper.NumberA = 1;oper.NumberB = 2;double result = oper.GetResult ();Console.WriteLine ("result = " + result.ToString());

工厂方法模式克服了简单工厂违背开闭原则的缺点,又保持了封装对象创建过程的优点。但缺点是每加一个产品,就需要增加一个产品工厂的类。简单工厂的判断是在工厂类里,工厂方法模式其实是把判断移到了客户端。不过,C#的反射机制可以解决分支判断的问题。嗯,后面再说。

0 0
原创粉丝点击