简单工厂模式
1. 面試受挫
# 面試受挫 class Program(object):def __init__(self):passdef getResult(self):a = int(input("請輸入數(shù)字:\n>>> "))c = input("請輸入運算符:\n>>> ")b = int(input("請輸入另一個數(shù)字:\n>>> "))if c == "+":r = a + belif c == "-":r = a - belif c == "*":r = a * belse:r = a / bprint("運算結(jié)果為: ", r)2. 初學者代碼毛病
- string A; string B; string C這樣的命名是非常不規(guī)范的.
- 判斷分支,這樣的寫法,意味著每個條件都要做判斷,等于計算機做了三次無用功.
- 如果除數(shù)時,客服端輸入了0怎么辦,如果用戶輸入的是字符符號而不是數(shù)字怎么辦.
3. 代碼規(guī)范
class Program(object):def __init__(self):passdef getResult(self):a = int(input("請輸入數(shù)字:\n>>> "))c = input("請輸入運算符:\n>>> ")b = int(input("請輸入另一個數(shù)字:\n>>> "))if c == "+":r = a + belif c == "-":r = a - belif c == "*":r = a * belse:if b == 0:print("除數(shù)不能為0,請重新輸入")exit(0)else:r = a / bprint("運算結(jié)果為: ", r)4. 面向?qū)ο缶幊?/h2>
碰到問題就直覺地用計算機能夠理解的邏輯來描述和表達待解決的問題及求解過程.這其實是計算機的方式思考,這并沒有錯.但是這樣的思維卻使得我們的程序只為滿足實現(xiàn)當前的需求,程序不容易維護,不容易擴展,更不容易復用.從而達不到高質(zhì)量代碼的要求.
5. 活字印刷,面向?qū)ο?/h2> - 在這之前,要修改,必須重刻;要加字,必須重刻;要重新排列,必須重刻;印完該書,此版毫無價值.
- 活字印刷:
 1) 要改,只需要改要改之字,可維護;
 2) 重復使用,可復用;
 3) 加字,另刻字加入即可,可擴展;
 4) 豎排橫排,將活字移動即可,靈活性好.
6. 面向?qū)ο蟮暮锰?/h2> 
1) 要改,只需要改要改之字,可維護;
2) 重復使用,可復用;
3) 加字,另刻字加入即可,可擴展;
4) 豎排橫排,將活字移動即可,靈活性好.
要改需求,更改最初的想法的事件,才逐漸明白當中的道理.
開始通過封裝,繼承,多態(tài)把程序的耦合性降低,用設(shè)計模式使得程序更加的靈活,容易修改,并且易于復用.
7. 復制與復用
復制,因為當你的代碼中重復的代碼多到一定程度,維護的時候,可能就是一場災難.越大的系統(tǒng),這種方式帶來的問題越嚴重,編程有一原則,就是用盡可能的辦法去避免重復.想想看,有哪些是和控制臺無關(guān),而哪些只是和計算器有關(guān)的.
8. 業(yè)務(wù)的封裝
讓業(yè)務(wù)邏輯與界面邏輯分開,讓它們之間的耦合度下降.
Operation運算類:
class Operation(object):@staticmethoddef getResult(numberA, op, numberB): # 這里就單個函數(shù)更簡單,但是還是用類來實現(xiàn),if op == "+":return numberA + numberBelif op == "-":return numberA - numberBelif op == "*":return numberA * numberBelse:return numberA / numberB客服端代碼:
if __name__ == "__main__":numberA = int(input("請輸入數(shù)字:\n>>> "))op = input("請輸入運算符:\n>>> ") # 這里略過對操作符的numberB = int(input("請輸入另一個數(shù)字:\n>>> "))try:print(Operation(numberA, op, number B)except ZeroDivisionError:return "除數(shù)不能為0"9. 緊耦合vs.松耦合
A: 如何做到很靈活的可修改和可擴展?比如說增加一個平方根運算,如何改?
B: 只需要修改Operation類就可以了,在switch中加一個分支就行了.
A: 問題是你要加一個平方根運算,卻需要讓加減乘除的運算都得來參與編譯.
B: 我應(yīng)該把加減乘除等運算分離,修改其中一個不影響另外的幾個,增加運算算法也不影響其他代碼?
A: 如何用繼承和多態(tài),你應(yīng)該有感覺了.
Operation運算類:
import abcclass Operation(abc.ABC):def __init__(self, numberA, numberB):self._numberA = numberAself._numberB = numberB@abc.abstractmethoddef getResult(self):raise NotImplementedErrorclass OperationAdd(Operation):def __init__(self, numberA, numberB):super(OperationAdd, self).__init__(numberA, numberB)def getResult(self):return self._numberA + self._numberBclass OperationSub(Operation):def __init__(self, numberA, numberB):super(OperationSub, self).__init__(numberA, numberB)def getResult(self):return self._numberA - self._numberBclass OperationMul(Operation):def __init__(self, numberA, numberB):super(OperationMul, self).__init__(numberA, numberB)def getResult(self):return self._numberB * self._numberAclass OperationDiv(Operation):def __init__(self, numberA, numberB):super(OperationDiv, self).__init__(numberA, numberB)def getResult(self):try:return self._numberA / self._numberBexcept ZeroDivisionError:return "除數(shù)不能為0"B: 我如何讓計算器知道我希望用哪一個算法呢?
10. 簡單工廠模式
A: 你現(xiàn)在的問題就是如何去實例化對象的問題,到底要實例化誰,將來會不會增加實例化的對象,比如增加開根運算,這是很容易變化的地方,應(yīng)該考慮用一個單獨的類做這個創(chuàng)造實例的過程,這就是工廠.
簡單運算工廠類:
class OperationFactory(object):_select = {"+": OperationAdd,"-": OperationSub,"*": OperationMul,"/": OperationDiv}@staticmethoddef createOperation(op):return OperationFactory._select.get(op)客服端代碼:
if __name__ == "__main__":numberA = int(input("請輸入數(shù)字:\n>>> "))op = input("請輸入運算符:\n>>> ") # 這里略過對操作符的判斷numberB = int(input("請輸入另一個數(shù)字:\n>>> "))opCls = OperationFactory.createOperation(op)operation = opCls(numberA, numberB)print(operation.getResult())A: 如果有一天我們需要更改加法運算,我們只需要改哪里?
B: 改OperationAdd就可以了.
A: 增加運算?
B: 只要增加相應(yīng)的運算子類就可以了.還要去修改運算類工廠,在switch中增加分支.
這幾個類的結(jié)構(gòu)圖:
11. UML類圖
編程是一門技術(shù),更是一門藝術(shù),不能只滿足于寫完代碼運行結(jié)果正確就完事了,時??紤]如何讓代碼更加簡練,更加容易維護,容易擴展和復用,只有這樣才能真正提高.
總結(jié)
 
                            
                        - 上一篇: 使用Axis2来构建Web Servic
- 下一篇: 解读《新一代人工智能发展规划》,企业如何
