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的分支,修改原有的类,这样违背了“开放-封闭”原则    

            

  • 相关阅读:
    Atitit 华为基本法 attilax读后感
    Atitit 华为管理者内训书系 以奋斗者为本 华为公司人力资源管理纲要 attilax读后感
    Atitit 项目版本管理gitflow 与 Forking的对比与使用
    Atitit 管理的模式扁平化管理 金字塔 直线型管理 垂直管理 水平管理 矩阵式管理 网状式样管理 多头管理 双头管理
    Atitit 乌合之众读后感attilax总结 与读后感结构规范总结
    深入理解 JavaScript 异步系列(4)—— Generator
    深入理解 JavaScript 异步系列(3)—— ES6 中的 Promise
    深入理解 JavaScript 异步系列(2)—— jquery的解决方案
    深入理解 JavaScript 异步系列(1)——基础
    使用 github + jekyll 搭建个人博客
  • 原文地址:https://www.cnblogs.com/loleina/p/7375508.html
Copyright © 2011-2022 走看看