您的位置:首页 > 其它

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

2017-03-27 20:05 281 查看

工厂模式

工厂模式是创建模式,主要是为创建对象提供过渡接口 ,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。

工厂模式在《深入浅出设计模式》和《大话设计模式》中分为三类:

简单工厂模式(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#的反射机制可以解决分支判断的问题。嗯,后面再说。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: