博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[Python设计模式] 第1章 计算器——简单工厂模式
阅读量:6271 次
发布时间:2019-06-22

本文共 4586 字,大约阅读时间需要 15 分钟。

github地址:

写在前面的话

"""读书的时候上过《设计模式》这一门课,当时使用的教材是程杰老师的《大话设计模式》,使用的语言是C#,学过课程之后初期深感面向对象思想的伟大,但是很少应用到实际开发中。后来我接触了Python,现在工作中用到最多的也是Python,或许是因为Python的便利性,我写的很多脚本/程序都还是面向过程编程,缺少面向对象的思想在里边。因此,我打算重读程杰老师的《大话设计模式》并用Python进行实践。"""                                                                                                                                                                                                                                        by ZH奶酪——张贺

题目

用一种面向对象语言实现一个计算器控制台程序, 要求输入两个数和运算符号(+-*/), 得到结果.

基础版本

a = int(input("input a number:"))b = str(input("input a operater(+ - * /):"))c = int(input("input a number:"))if b == "+":    print(a+c)elif b == "-":    print(a-c)elif b == "*":    print(a*c)else b == "/":    print(a/c)
input a number:16input a operater(+ - * /):*input a number:232

点评

  1. 变量命名不规范
  2. 无用的if条件判断太多
  3. 除法运算中未考虑第二个数字为0的情况

改进版本1.0——规范代码

number_a = int(input("input a number:"))operator = str(input("input a operater(+ - * /):"))number_b = int(input("input a number:"))if operator == "+":    print(number_a + number_b)elif operator == "-":    print(number_a - number_b)elif operator == "*":    print(number_a * number_b)elif operator == "/":    if number_b != 0:        print(number_a / number_b)    else:        print("With operator '/', the second number can not be zero.")else:    print("Wrong operator.")
input a number:12input a operater(+ - * /):/input a number:0With operator '/', the second number can not be zero.

点评

  1. 没有使用面向对象的思想
  2. 只满足当前需求, 不易维护, 不易扩展, 不易复用, 不够灵活

为什么活字印刷术能位列四大发明?主要是其方法的思想。

  1. 文章改字方便, 可维护
  2. 一个字可以重复使用, 可复用
  3. 文章加字容易, 可扩展
  4. 文章改版只需移动活字, 灵活性好

复制?复用?

如果做一个带图形化界面的计算器,上边的代码需要再写一次。为了避免这样,需要将业务逻辑界面逻辑分开,降低耦合度。

改进版本2.0——利用封装解耦

class Operation():    def __init__(self):        self.result = None    def get_result(self, number_a, number_b, operator):        if operator == "+":            self.result = number_a + number_b        elif operator == "-":            self.result = number_a - number_b        elif operator == "*":            self.result = number_a * number_b        elif operator == "/":            if number_b != 0:                self.result = number_a / number_b            else:                print("With operator '/', the second number can not be zero.")        else:            print("Wrong operator.")        return self.resultnumber_a = int(input("input a number:"))operator = str(input("input a operater(+ - * /):"))number_b = int(input("input a number:"))operation = Operation()print(operation.get_result(number_a, number_b, operator))
input a number:12input a operater(+ - * /):+input a number:1224

点评

  1. 仅仅用到了封装, 还没用到继承和多态。

紧耦合?松耦合?

如果要支持一个开根号运算,上边的代码需要改动包括加减乘除在内的get_result函数,应该将加减乘除运算分离, 修改其中一个不影响其他的几个。那么就需要定义一个Operator基类, 将get_result定义为虚函数,然后通过继承和多态,分别实现加减乘除四个子类,每个子类中定义虚函数的实现逻辑。

参考资料:

改进版本3.0——简单工厂模式

from abc import ABCMeta, abstractmethodclass Operation():    __metaclass__ = ABCMeta    def __init__(self):        self.result = None    @abstractmethod    def get_result(self):        pass    class AddOperation(Operation):        def get_result(self, number_a, number_b):        self.result = number_a + number_b        return self.result    class SubOperation(Operation):    def get_result(self, number_a, number_b):        self.result = number_a - number_b        return self.result    class MulOperation(Operation):    def get_result(self, number_a, number_b):        self.result = number_a * number_b        return self.result        class DivOperation(Operation):    def get_result(self, number_a, number_b):        if number_b == 0:            print("With operator '/', the second number can not be zero.")            return self.result        self.result = number_a / number_b        return self.result

如何实例化?——简单工厂模式

现在加减乘除的实现逻辑已经进一步隔离,之后即使增加一个开根号运算符,也和加减乘除无关。那么如何去实例化这些类呢?可以用简单工厂模式

class OperationFactory():        @classmethod    def create_operate(self, operator):        oper = None        if operator == "+":            oper = AddOperation()        elif operator == "-":            oper = SubOperation()        elif operator == "*":            oper = MulOperation()        elif operator == "/":            oper = DivOperation()        else:            print("Wrong operator.")        return oper

通过上边的简单工厂,输入运算符号,就可以实例化出对应的对象。下边是客户端的代码。

number_a = int(input("input a number:"))operator = str(input("input a operater(+ - * /):"))number_b = int(input("input a number:"))oper = OperationFactory.create_operate(operator)print(oper.get_result(number_a, number_b))
input a number:12input a operater(+ - * /):-input a number:120

点评

  1. 业务逻辑与界面逻辑隔离,不关心是控制台程序还是GUI程序
  2. 不同运算逻辑隔离,一个运算符的增删改操作不会影响其他运算
  3. 面向对象思想的封装,继承,多态都有所体现
  4. 易维护,易扩展,易复用

转载地址:http://zblpa.baihongyu.com/

你可能感兴趣的文章
Android学Jni/Ndk 开发记录(一)
查看>>
Linux Tcl和Expect的安装
查看>>
WPF中的依赖项属性(转)
查看>>
linux防火墙相关 iptables
查看>>
最简单的单例模式
查看>>
JPopupMenu的使用以及JPopupMenu中子组件的事件处理
查看>>
从反汇编的角度看引用和指针的区别
查看>>
拓马长枪定乾坤
查看>>
UIProgressView的详细使用
查看>>
Silverlight实用窍门系列:70.Silverlight的视觉状态组VisualStateGroup
查看>>
照片筛选与上传功能
查看>>
Hello ZED
查看>>
常见web攻击方式
查看>>
hdu 4472
查看>>
oracle存储过程中is和as区别
查看>>
windows 2003 群集
查看>>
几个gcc的扩展功能
查看>>
Spark一个简单案例
查看>>
关于结构体占用空间大小总结(#pragma pack的使用)
查看>>
通过浏览器查看nginx服务器状态配置方法
查看>>