python开发中常用的设计模式(简单工厂模式)

原文取自大话设计模式,不同之处在于原文是基于C#编写的,我在这里用Python表述

需求:使用python语言开发实现2个数相加减及扩展的计算器

初学者代码如下:

if __name__ == "__main__":
    print("请输入数字A:")
    a = input()
    print("请输入数字B:")
    b = input()
    print("请输入运算符:")
    c = input()
    if (c == "+"):
        print(int(a) + int(b))
    elif (c == "-"):
        print(a - b)
    elif (c == "*"):
        print(a * b)
    else:
        print(a / b)

注意,Python无法使用switch语句。

上述代码的缺点,如果要添加其他运算方式或修改已有的运算方式,那么每次修改都要在上述的elif语句里面添加新的条件或修改已有的代码,完全不具备扩展性和维护性。(哪怕将上述的非核心代码封装到某个方法中,依然如此)

对上述代码进行修改:

首先引入包:

import abc

然后提取上述需求中不改变的东西为基类:

这里定义a,b为operation类的两个类变量

# 定义运算类
# python的抽象方法必须含有至少一个参数,默认使用self函数
# 子类使用父类变量是,必须通过self对象、等同于this
class operation():
    a = 0
    b = 0
    @abc.abstractmethod
    def getResult(self):
        pass

定义一个获取结果的getResult方法,且该方法是抽象方法。

使用@abc.abstractmethod声明的方法为抽象方法,该方法需要其继承类重新改写

然后定义上述基类的实现类(主要是实现上述类的抽象方法),即对基类进行扩展改造:

# 运算类的实现类-加运算
class operationAdd(operation):
    def getResult(self):
        print(int(self.a) + int(self.b))


# 运算类的实现类-减运算
class operationSub(operation):
    def getResult(self):
        print(int(self.a)  - int(self.b))

# #############################
# 可以继续添加其他运算类的实现类
# #############################

定义运算工厂类,用来获取实现类:

# 运算工厂类
class operationFactory():
    # 运算类的静态方法
    @staticmethod
    def createOperation(operation):
        opera = None
        # 这里可以添加其他运算方法
        if (operation == "+"):
            opera = operationAdd()
        elif (operation == "-"):
            opera = operationSub()
        elif (operation == "*"):
            pass
        else:
            pass
        return opera

最后就是主函数:

if __name__ == "__main__":
    print("请输入数字A:")
    a = input()
    print("请输入数字B:")
    b = input()
    print("请输入运算符:")
    c = input()
    opera = operationFactory.createOperation(c)
    opera.a = a
    opera.b = b
    opera.getResult()

在主函数中,operationFactory.createOperation方法可以根据你的输入,获取指定的运算对象。

然后通过指定的运算对象,调用其getResult()方法就可以获取该类特有的运算结果。

优点:无论添加多少新的运算方式,只要使其重写基类的抽象函数,再在工厂类中添加相应的分支代码,就可以获取该类的特有运算结果。

缺点:添加新的运算类需要修改工厂方法,每次添加,工厂类都要重新打包编译。

 

总结:

#一个实体类(包含抽象方法),实体类的实现类 (扩展类)

# 一个工厂类(用来根据不同需求实例化不同实现类)、

# 一个主函数

# 即通过工厂类获取【基类的实现类】,然后调用【基类的实现类】的特定抽象方法,获取对应结果

 

编码中的小发现:

# 说起来python的类变量、突然想起来ptyhon中是否含有类的静态变量这个东西。
# 然后就敲了下面的代码使其和C#代码进行对比。
# 对比发现,python和C#的一点点不同,python类里面定义的变量,如果通过类名去改变,则所有的实例对象的变量都会受到影响。
# class demo():
#     a=10


# if __name__ == "__main__":
#     demoB = demo()
#     demoB.a = 1
#     demo.a = 100
#     demoA = demo()
#     demoB = demo()
#     print(demoA.a, demoB.a)

# 这里输出100,100


# if __name__ == "__main__":
#
#     demoA=demo()
#     demoA.a=100
#     demoB=demo()
#     print(demoA.a,demoB.a)
# 这里输出100,10

不对之处敬请指正!

    原文作者:豆芽胡
    原文地址: https://blog.csdn.net/u012605477/article/details/88540676
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞