首页 > 代码库 > 工厂方法模式

工厂方法模式

《简单工厂模式》

          在简单工厂中我们如果要Operation类中添加新的运算符(开根)则需要在switch语句中添加一个分支,但是却暴露了Operation类其他运算符的运算代码,为了满足开闭原则,我们抽象出一个父类Operation和四个子类OperationAdd,OperationSub,OperationMul,OperationDiv.当需要添加新的运算符时只需要添加一个Operation类的子类即可。

         工厂类中通过传入的参数实例化出相应的对象oper = OperationFactory.CreateOperate("+")添加新的子类时,工厂类的switch语句中也要添加一个分支,所以简单工厂模式并不符合开闭原则

计算器例子的结构图


         我们已经知道了简单工厂模式中,工厂类与其中的分支耦合,所以我们根据依赖倒转原则,把工厂类抽象为一个接口,这个接口有个方法创建抽象产品,然后所有的要生产具体类的工厂来实现这个接口。最后一个简单的工厂类,就变成了一个工厂抽象接口和具体生成对象的工厂。


工厂方法模式

定义:一个接口的方法用来创建抽象产品,所有的要生产具体的工厂去实现这个接口。

结构图如下:


工厂方法模式中运算器的例子结构图


运算器例子代码如下:

运算类

public class Operation  
{  
     private  double _numberA =0;  
     private  double _numberB =0;  
     
    public double NumberA  
    {  
           get { return  _numberA;}  
           set(  _numerA = value;)  
     }  
    
    public double NumberB  
    {  
           get { return  _numberB;}  
           set(  _numerB = value;)  
     }  
    public victual  double GerResult()  
    {  
           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;  
    }  
}

class OperationMul : Operation  
{
    public override double GetResult()
   {        
         double result = 0;  
         result = numberA * numberB;  
         return result;  
    }  
}
  
class OperationDiv:Operation  
{  
    public override double GetResult()
   {
         double result = 0;  
         if(numberB==0)
             throw new Exception("除数不能为0。");
         result = numberA /numberB;  
         return result;  
    }
}

工厂接口

interface IFactory
{
     Operation CreateOperation();
}
四个具体工厂子类

class AddFactory:IFactory
{
    public Operation CreateOperation()
    {
         return new OperationAdd();
    }
}
class SubFactory:IFactory
{
    public Operation CreateOperation()
    {
         return new OperationSub();
    }
}
class MulFactory:IFactory
{
    public Operation CreateOperation()
    {
         return new OperationMul();
    }
}
class DivFactory:IFactory
{
    public Operation CreateOperation()
    {
         return new OperationDiv();
    }
}
客户端

IFactory operFactory = new AddFactory();
Operation oper = operFactory.CreateOperation();
oper.numberA = 1;
oper.numberB = 2;
double result = oper.GetResult();

工厂方法模式,完全符合开闭原则,当添加新的运算符(开根)时,添加Operation类和IFactory类的相应的子类即可实现系统的扩展。


总结:工厂方法模式虽然完全符合了开闭原则,有利于系统的扩展,但却多添加了类,同时工厂方法模式的实现,是把简单工厂的内部逻辑判断移到了客户端代码来判断,一个修改工厂类,一个修改客户端,感觉工厂方法模式的优势并不太明显。