zoukankan      html  css  js  c++  java
  • 一起来学设计模式-----创建型模式之简单工厂

             一直都特别想整体学习下设计模式,之前总觉得不是时候,觉得基础不够好怕吸收不了,或者体会不到设计模式带来的便利。就在上半年的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的分支,修改原有的类,这样违背了“开放-封闭”原则    

            

  • 相关阅读:
    Python入门系列——第20篇
    Python入门系列——第19篇
    windows下python使用pip命令安装builtwith库时,遇到的utf-8问题的解决
    Python入门系列——第18篇
    在相同的主机上创建一个duplicate数据库
    duplicate database的时候,rman连接 auxiliary database的后状态不正确
    使用duplicate target database ... from active database复制数据库
    RHEL7
    Oracle 监听器日志文件过大导致监听异常
    TNS-01251: Cannot set trace/log directory under ADR
  • 原文地址:https://www.cnblogs.com/loleina/p/7375508.html
Copyright © 2011-2022 走看看