要求
实现一个简单计算器
思路
Iter1 初始草稿
#!/usr/bin/python
#coding:utf-8
if __name__ == "__main__":
A = raw_input("请输入数字A: ")
B = raw_input("请输入运算符号(+、-、*、/): ")
C = raw_input("请输入数字B: ")
if B == "+":
D = float(A) + float(C)
if B == "-":
D = float(A) - float(C)
if B == "*":
D = float(A) * float(C)
if B == "/":
D = float(A) / float(C)
print "结果是: ", D
问题:
命名不规范
异常判断
判断分支多次做无用功
Iter2 进一步规范化
#!/usr/bin/python
#coding:utf-8
if __name__ == "__main__":
try:
strNumberA = raw_input("请输入数字A: ")
strOperate = raw_input("请输入运算符号(+、-、*、/): ")
strNumberB = raw_input("请输入数字B: ")
swithcer = {
"+": float(strNumberA) + float(strNumberB),
"-": float(strNumberA) - float(strNumberB),
"*": float(strNumberA) * float(strNumberB),
"/": float(strNumberA) / float(strNumberB)
}
D = swithcer[strOperate]
print "结果是: ", D
except Exception, e:
print "结果有错: ", e
问题:
达不到高质量代码的要求
不易维护
不易扩展
不易复用
即完成之后是否还有被利用的价值
Iter3 封装业务
#!/usr/bin/python
# coding:utf-8
class Operation:
def __init__(self, numberA, numberB):
self.numberA = numberA
self.numberB = numberB
def getresult(self, operate):
swithcer = {
"+": float(self.numberA) + float(self.numberB),
"-": float(self.numberA) - float(self.numberB),
"*": float(self.numberA) * float(self.numberB),
"/": float(self.numberA) / float(self.numberB)
}
return swithcer[operate]
if __name__ == "__main__":
try:
strNumberA = raw_input("请输入数字A: ")
strOperate = raw_input("请输入运算符号(+、-、*、/): ")
strNumberB = raw_input("请输入数字B: ")
D = Operation(strNumberA, strNumberB).getresult(strOperate)
print "结果是: ", D
except Exception, e:
print "结果有错: ", e
问题:
耦合太高
若要增加一个运算,却需要其他的运算都来参加编译
安全性,对于原有的代码有风险
Iter4 松耦合
#!/usr/bin/python
# coding:utf-8
class Operation:
def __init__(self, numberA, numberB):
self.numberA = numberA
self.numberB = numberB
# 父类需不需要有getresult(self)方法,为什么?
class OperationAdd(Operation):
def getresult(self):
return float(self.numberA) + float(self.numberB)
class OperationSub(Operation):
def getresult(self):
return float(self.numberA) - float(self.numberB)
class OperationMul(Operation):
def getresult(self):
return float(self.numberA) * float(self.numberB)
class OperationDiv(Operation):
def getresult(self):
return float(self.numberA) / float(self.numberB)
以上松耦合,修改任何一个算法,不需要提供其他算法的代码
问题:
实例化问题(如何知道调用哪个运算方法?)
Iter5 简单工厂模式
用一个单独的类来选择调用,即工厂。
#!/usr/bin/python
# coding:utf-8
class OperationFactory:
@staticmethod
def createOperate(operate):
switcher = {
"+": OperationAdd(),
"-": OperationSub(),
"*": OperationMul(),
"/": OperationDiv()
}
return switcher[operate]
class Operation:
numberA = 0
numberB = 0
def getresult(self):
return 0
class OperationAdd(Operation):
def getresult(self):
return float(self.numberA) + float(self.numberB)
class OperationSub(Operation):
def getresult(self):
return float(self.numberA) - float(self.numberB)
class OperationMul(Operation):
def getresult(self):
return float(self.numberA) * float(self.numberB)
class OperationDiv(Operation):
def getresult(self):
return float(self.numberA) / float(self.numberB)
if __name__ == "__main__":
try:
strNumberA = raw_input("请输入数字A: ")
strOperate = raw_input("请输入运算符号(+、-、*、/): ")
strNumberB = raw_input("请输入数字B: ")
oper = OperationFactory.createOperate(strOperate)
oper.numberA = float(strNumberA)
oper.numberB = float(strNumberB)
D = oper.getresult()
print "结果是: ", D
except Exception, e:
print "结果有错: ", e
这样一来,只需要输入运算符号,工厂就实例化出合适的对象。通过多台,返回父类的方式实现了计算器的结果。
任何程序都可以通过调用工厂来实现计算器的功能。
UML图
SimpleFactory
细碎python
@staticmethod 用途及用法
异常捕获机制
python 子类父类调用关系
raw_input() 与 input() 区别
python3.x中仅有input(),将一切输入视作字符串
python2.x中
in\out
raw_input()
input()
str
str
str(需加引号)
int
str
int
bool
str
bool
表达式
str
结果值
Ps
果然写下来一目了然,写下来才能理解。
用3个小时整理输出,其中很多涉及到Python的细碎的知识也需要花时间整理。
在设计模式之后,还有算法、网络编程、数据库等知识,需要浸入。
平静是本事,持续平静是习惯。
已经4月底,夏天要来了。