一起来学设计模式-----创建型模式之简单工厂

         一直都特别想整体学习下设计模式,之前总觉得不是时候,觉得基础不够好怕吸收不了,或者体会不到设计模式带来的便利。就在上半年的KPI编写测试桩项目中,我就深刻的感受到设计模式带来的好处。一般测试人员写的代码不是很多,很多时候写代码也都是基于解决问题的逻辑来的,写的代码面向过程思路较多,因此代码的冗余度特别大。在编写一个大的测试工具时,就更应该考虑这方面的问题自己是否存在。刻不容缓的学习起了设计模式,整理就从创建型模式的工厂模式开始入手吧。

         创建型模式,共三种:工厂方法模式、建造者模式、原型模式。其中工厂模式,又分简单工厂,工厂方法,和抽象工厂三类。创建型模式,基于现在我对这个概念的理解,主要就是用来获取对象的。这一章主要是总结简单工厂的实现和优缺点。

        现在需要实现一个计算功能,做一个能实现加减乘除的小程序。最开始应该是这样写的:

def operate(a,b,op):
    if op =='+':
        return a+b
    elif op =='-':
        return a-b
    elif op =='*':
        return a*b
    elif op== '/':
        return a/b
    else:
        return 'op error!'

if __name__ == '__main__':
    print operate(2,2,'+')

       我得承认,大部分时候我写的脚本都是这样的,单从测试的角度就有1个bug(除法计算未考虑分子为0的情况),从设计角度上就有更大的缺陷,只满足了面向对象的一个特征(封装),还有继承和抽象完成没有考虑,如果再增加一个N的平方的计算,得改动所有的代码。彻底的违背了设计的开发-关闭原则(对扩展开放,对修改关闭)。
      使用设计的模式来考虑,首先无论何种运算,都是实现2个数之间的运算。可以由此抽象出一个基类BaseOperation

class BaseOperation:
    def GetResult(self,a,b):
        result = 0
        return result

 在此基础上,其他的运算都继承实现各自的特定计算,根据需求重写GetResult

class OperationAdd(BaseOperation):
    def __int__(self,a,b):
        self.a = a
        self.b = b

    def GetResult(self,a,b):
        result = 0
        result = a + b
        return result

class OperationSub(BaseOperation):
    def __int__(self,a,b):
        self.a = a
        self.b = b

    def GetResult(self,a,b):
        result = 0
        result = a - b
        return result

class OperationMul(BaseOperation):
    def GetResult(self,a,b):
        result = 0
        result = a * b
        return result

class OperationDiv(BaseOperation):
    def GetResult(self,a,b):
        result = 0
        if b == 0 :
            raise ValueError("no 0 !")
        result = a/b
        return result

  最后一个方法封装调用的逻辑给客户端生成对象使用,客户端传需要的操作,就能得到相应实例。如下所示:

def  OperationFactory(operate):
    oper = None
    if operate == '+':
        oper = OperationAdd()
    elif operate == '-':
        oper = OperationSub()
    elif operate == '*':
        oper = OperationMul()
    elif operate == '/':
        oper = OperationDiv()
    else:
       raise ValueError("only support + - * /")
    return oper

客户端调用如下:

def main():
    oper = OperationFactory('/')
    print oper.GetResult(3,0)

if __name__=='__main__':
    main()

     这样实现后,如果需要再增加一个运算,改动量就相对少了些,客户端不需要修改,只需要传递不同的入参,服务端编写一个类,增加工厂方法对应的处理即可。一个简单的工厂方法模式就诞生了,简单工厂,它是一个方法,或者说就是一个函数,对不同的输入参数返回不同的对象uml类图如下:

 

 

总结下:

简单工厂模式总结
优点:
     在于工厂类中包含了必要的逻辑判断,需要根据客户端的选择条件动态的实例化相关的类,对于客户端来说,去除与具体产品的依赖,客户端不管是哪个类,只需要把自己知道的参数传递给工厂,工厂就会给出响应的实例,客户端只需要拿着实例调用接口即可。
缺点:
     如果需要新增一个类,则需要修改工厂类的case的分支,修改原有的类,这样违背了“开放-封闭”原则    

 

 

        

posted @ 2017-08-16 20:02  loleina  阅读(346)  评论(0编辑  收藏  举报