github地址:https://github.com/cheesezh/python_design_patterns

写在前面的话

"""
读书的时候上过《设计模式》这一门课,当时使用的教材是程杰老师的《大话设计模式》,使用的语言是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:16
input a operater(+ - * /):*
input a number:2
32

点评

  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:12
input a operater(+ - * /):/
input a number:0
With operator '/', the second number can not be zero.

点评

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

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

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

复制?复用?

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

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

class Operation():def __init__(self):self.result = Nonedef get_result(self, number_a, number_b, operator):if operator == "+":self.result = number_a + number_belif operator == "-":self.result = number_a - number_belif operator == "*":self.result = number_a * number_belif operator == "/":if number_b != 0:self.result = number_a / number_belse: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:12
input a operater(+ - * /):+
input a number:12
24

点评

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

紧耦合?松耦合?

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

参考资料: Python中的多态与虚函数

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

from abc import ABCMeta, abstractmethodclass Operation():__metaclass__ = ABCMetadef __init__(self):self.result = None@abstractmethoddef get_result(self):passclass AddOperation(Operation):def get_result(self, number_a, number_b):self.result = number_a + number_breturn self.resultclass SubOperation(Operation):def get_result(self, number_a, number_b):self.result = number_a - number_breturn self.resultclass MulOperation(Operation):def get_result(self, number_a, number_b):self.result = number_a * number_breturn self.resultclass 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.resultself.result = number_a / number_breturn self.result

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

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

class OperationFactory():@classmethoddef create_operate(self, operator):oper = Noneif 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:12
input a operater(+ - * /):-
input a number:12
0

点评

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

转载于:https://www.cnblogs.com/CheeseZH/p/9363197.html

[Python设计模式] 第1章 计算器——简单工厂模式相关推荐

  1. [Python设计模式] 第8章 学习雷锋好榜样——工厂方法模式

    github地址:https://github.com/cheesezh/python_design_patterns 简单工厂模式 v.s. 工厂方法模式 以简单计算器为例,对比一下简单工厂模式和工 ...

  2. 设计模式学习笔记二:简单工厂模式

    含义: 从设计模式的类型上来说,简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一.简单工厂模式是由一个工厂对象决定创 ...

  3. 设计模式【2.1】-- 简单工厂模式怎么演变成工厂方法模式?

    还记得前面的简单工厂模式么?我们开了一个水果工厂FruitFactory,生产三种水果Apple,Pear,Orange.今天给大家讲讲工厂方法模式: 老板搞水果工厂赚了点小钱,准备扩大生产,每个工厂 ...

  4. 常用设计模式系列(一)—简单工厂模式

    hello各位程序员大哥大姐好,上期我讲解了设计模式的概念及分类,学习了UML类图的认识,今天我们就趁热打铁,学习一下简单工厂模式,以后每一个模式会出一篇文章,供各位及我自己查阅学习.斗图还是不能忘的 ...

  5. 设计模式学习-每日一记(1.简单工厂模式)

    简单工厂模式 A.定义: 定义一个用于创建对象的接口. B.定义分析: "定义一个用于创建对象的接口". 这个模式的应用主要是定义一个接口,每个类都会有接口,对于面向对象语言就是定 ...

  6. 设计模式学习(1)简单工厂模式:君子远庖厨

    一.题引 在<孟子·梁惠王上>有如此一句话:"君子之于禽兽也,见其生,不忍见其死:闻其声,不忍食其肉.是以君子远庖厨也."翻译过来意思是:"君子对于飞禽走兽, ...

  7. C++设计模式-使用Qt框架采用简单工厂模式实现商城打折满减案例

    程序运行截图如下: 理论: 面向对象的编程,并不是类越多越好,类的划分是为了封装,但分类的基础是抽象,具有相同属性和功能的对象的抽象集合才是类. 注意:这个模式值解决了对象创建的问题,工厂本身包含了所 ...

  8. python制作小人,[Python设计模式] 第13章 造小人——建造者模式

    题目1 用程序模拟一个画小人的过程,要求小人要有头,身子,左手,右手,左脚,右脚. 基础代码 class PersonDrawer(): def draw(self): print("画头& ...

  9. 【Python学习随笔】依赖倒置原则 + 简单工厂模式

    记录一下Python学习中的点滴,分享一段代码. [问题背景]在不同的系统平台需要执行一段有差异的指令,该如何写出更优雅的代码? [知识点]依赖倒置原则 + 简单工厂模式 [代码分享] #!/usr/ ...

最新文章

  1. Spark运行模式Local+Standalone+Yarn+mesos
  2. 你不可不知的9种Lisp语言思想
  3. 实现在Android本地视频播放器开发
  4. Fedora中允许mysql远程访问的几种方式
  5. ASP.NET应用程序设计的10大技巧
  6. SAP ABAP Netweaver和Hybris Commerce的部署策略
  7. python中遇到循环import即circular import的问题原理剖析及解决方案
  8. springboot 创建地址_使用 SpringBoot Admin监控Spring Boot 服务
  9. Js跨域解决方法总结
  10. Android用户界面 UI组件--AdapterView及其子类(一) ListView及各种Adapter详解
  11. 批处理文件怎么写_Spring Boot快速入门:批处理与任务调度
  12. ubuntu apt-get 安装软件时自动yes
  13. FTPClient使用中的问题--获取当前工作目录为null
  14. hl usb-rs232驱动
  15. Flutter 实现吹气球动画
  16. fasttext文本分类python实现_一个使用fasttext训练的新闻文本分类器/模型
  17. JVM虚拟机——初识
  18. 【2018.10.4】CXM笔记(图论)
  19. mac 苹果如何才能实现剪切文件
  20. kali2020安装搜狗输入法

热门文章

  1. WebGL three.js学习笔记 6种类型的纹理介绍及应用
  2. PYPL 二月榜单发布:最受欢迎的编程语言、IDE 和数据库都是哪些
  3. 简单的聊聊,顺便招前端
  4. 大数据时代数据库-云HBase架构生态实践
  5. hdu-3015 Disharmony Trees---离散化+两个树状数组
  6. linux安装mysql5.7.19
  7. 黄聪:WordPress 启用HTTPS设置(转)
  8. [Oracle]高效的PL/SQL程序设计(三)--Package的优点
  9. Android开发中java.lang.RuntimeException: Unable to start activity ComponentInfo{xxx}: java.lang.NullPoi
  10. Document is invalid: no grammar found. at (null:3:8)