简单工厂模式与工厂方法模式

工厂模式

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

  • 简单工厂模式(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#的反射机制可以解决分支判断的问题。嗯,后面再说。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值