[Python设计模式] 第1章 计算器——简单工厂模式
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
点评
- 变量命名不规范
- 无用的if条件判断太多
- 除法运算中未考虑第二个数字为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.
点评
- 没有使用面向对象的思想
- 只满足当前需求, 不易维护, 不易扩展, 不易复用, 不够灵活
为什么活字印刷术能位列四大发明?主要是其方法的思想。
- 文章改字方便, 可维护
- 一个字可以重复使用, 可复用
- 文章加字容易, 可扩展
- 文章改版只需移动活字, 灵活性好
复制?复用?
如果做一个带图形化界面的计算器,上边的代码需要再写一次。为了避免这样,需要将业务逻辑
与界面逻辑
分开,降低耦合度。
改进版本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
点评
- 仅仅用到了封装, 还没用到继承和多态。
紧耦合?松耦合?
如果要支持一个开根号运算,上边的代码需要改动包括加减乘除在内的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
点评
- 业务逻辑与界面逻辑隔离,不关心是控制台程序还是GUI程序
- 不同运算逻辑隔离,一个运算符的增删改操作不会影响其他运算
- 面向对象思想的封装,继承,多态都有所体现
- 易维护,易扩展,易复用
转载于:https://www.cnblogs.com/CheeseZH/p/9363197.html
[Python设计模式] 第1章 计算器——简单工厂模式相关推荐
- [Python设计模式] 第8章 学习雷锋好榜样——工厂方法模式
github地址:https://github.com/cheesezh/python_design_patterns 简单工厂模式 v.s. 工厂方法模式 以简单计算器为例,对比一下简单工厂模式和工 ...
- 设计模式学习笔记二:简单工厂模式
含义: 从设计模式的类型上来说,简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一.简单工厂模式是由一个工厂对象决定创 ...
- 设计模式【2.1】-- 简单工厂模式怎么演变成工厂方法模式?
还记得前面的简单工厂模式么?我们开了一个水果工厂FruitFactory,生产三种水果Apple,Pear,Orange.今天给大家讲讲工厂方法模式: 老板搞水果工厂赚了点小钱,准备扩大生产,每个工厂 ...
- 常用设计模式系列(一)—简单工厂模式
hello各位程序员大哥大姐好,上期我讲解了设计模式的概念及分类,学习了UML类图的认识,今天我们就趁热打铁,学习一下简单工厂模式,以后每一个模式会出一篇文章,供各位及我自己查阅学习.斗图还是不能忘的 ...
- 设计模式学习-每日一记(1.简单工厂模式)
简单工厂模式 A.定义: 定义一个用于创建对象的接口. B.定义分析: "定义一个用于创建对象的接口". 这个模式的应用主要是定义一个接口,每个类都会有接口,对于面向对象语言就是定 ...
- 设计模式学习(1)简单工厂模式:君子远庖厨
一.题引 在<孟子·梁惠王上>有如此一句话:"君子之于禽兽也,见其生,不忍见其死:闻其声,不忍食其肉.是以君子远庖厨也."翻译过来意思是:"君子对于飞禽走兽, ...
- C++设计模式-使用Qt框架采用简单工厂模式实现商城打折满减案例
程序运行截图如下: 理论: 面向对象的编程,并不是类越多越好,类的划分是为了封装,但分类的基础是抽象,具有相同属性和功能的对象的抽象集合才是类. 注意:这个模式值解决了对象创建的问题,工厂本身包含了所 ...
- python制作小人,[Python设计模式] 第13章 造小人——建造者模式
题目1 用程序模拟一个画小人的过程,要求小人要有头,身子,左手,右手,左脚,右脚. 基础代码 class PersonDrawer(): def draw(self): print("画头& ...
- 【Python学习随笔】依赖倒置原则 + 简单工厂模式
记录一下Python学习中的点滴,分享一段代码. [问题背景]在不同的系统平台需要执行一段有差异的指令,该如何写出更优雅的代码? [知识点]依赖倒置原则 + 简单工厂模式 [代码分享] #!/usr/ ...
最新文章
- Spark运行模式Local+Standalone+Yarn+mesos
- 你不可不知的9种Lisp语言思想
- 实现在Android本地视频播放器开发
- Fedora中允许mysql远程访问的几种方式
- ASP.NET应用程序设计的10大技巧
- SAP ABAP Netweaver和Hybris Commerce的部署策略
- python中遇到循环import即circular import的问题原理剖析及解决方案
- springboot 创建地址_使用 SpringBoot Admin监控Spring Boot 服务
- Js跨域解决方法总结
- Android用户界面 UI组件--AdapterView及其子类(一) ListView及各种Adapter详解
- 批处理文件怎么写_Spring Boot快速入门:批处理与任务调度
- ubuntu apt-get 安装软件时自动yes
- FTPClient使用中的问题--获取当前工作目录为null
- hl usb-rs232驱动
- Flutter 实现吹气球动画
- fasttext文本分类python实现_一个使用fasttext训练的新闻文本分类器/模型
- JVM虚拟机——初识
- 【2018.10.4】CXM笔记(图论)
- mac 苹果如何才能实现剪切文件
- kali2020安装搜狗输入法
热门文章
- WebGL three.js学习笔记 6种类型的纹理介绍及应用
- PYPL 二月榜单发布:最受欢迎的编程语言、IDE 和数据库都是哪些
- 简单的聊聊,顺便招前端
- 大数据时代数据库-云HBase架构生态实践
- hdu-3015 Disharmony Trees---离散化+两个树状数组
- linux安装mysql5.7.19
- 黄聪:WordPress 启用HTTPS设置(转)
- [Oracle]高效的PL/SQL程序设计(三)--Package的优点
- Android开发中java.lang.RuntimeException: Unable to start activity ComponentInfo{xxx}: java.lang.NullPoi
- Document is invalid: no grammar found. at (null:3:8)