python開發中常用的設計模式(簡單工廠模式)

豆芽胡發表於2019-03-13

原文取自大話設計模式,不同之處在於原文是基於C#編寫的,我在這裡用Python表述

需求:使用python語言開發實現2個數相加減及擴充套件的計算器

初學者程式碼如下:

if __name__ == "__main__":
    print("請輸入數字A:")
    a = input()
    print("請輸入數字B:")
    b = input()
    print("請輸入運算子:")
    c = input()
    if (c == "+"):
        print(int(a) + int(b))
    elif (c == "-"):
        print(a - b)
    elif (c == "*"):
        print(a * b)
    else:
        print(a / b)

注意,Python無法使用switch語句。

上述程式碼的缺點,如果要新增其他運算方式或修改已有的運算方式,那麼每次修改都要在上述的elif語句裡面新增新的條件或修改已有的程式碼,完全不具備擴充套件性和維護性。(哪怕將上述的非核心程式碼封裝到某個方法中,依然如此)

對上述程式碼進行修改:

首先引入包:

import abc

然後提取上述需求中不改變的東西為基類:

這裡定義a,b為operation類的兩個類變數

# 定義運算類
# python的抽象方法必須含有至少一個引數,預設使用self函式
# 子類使用父類變數是,必須通過self物件、等同於this
class operation():
    a = 0
    b = 0
    @abc.abstractmethod
    def getResult(self):
        pass

定義一個獲取結果的getResult方法,且該方法是抽象方法。

使用@abc.abstractmethod宣告的方法為抽象方法,該方法需要其繼承類重新改寫

然後定義上述基類的實現類(主要是實現上述類的抽象方法),即對基類進行擴充套件改造:

# 運算類的實現類-加運算
class operationAdd(operation):
    def getResult(self):
        print(int(self.a) + int(self.b))


# 運算類的實現類-減運算
class operationSub(operation):
    def getResult(self):
        print(int(self.a)  - int(self.b))

# #############################
# 可以繼續新增其他運算類的實現類
# #############################

定義運算工廠類,用來獲取實現類:

# 運算工廠類
class operationFactory():
    # 運算類的靜態方法
    @staticmethod
    def createOperation(operation):
        opera = None
        # 這裡可以新增其他運算方法
        if (operation == "+"):
            opera = operationAdd()
        elif (operation == "-"):
            opera = operationSub()
        elif (operation == "*"):
            pass
        else:
            pass
        return opera

最後就是主函式:

if __name__ == "__main__":
    print("請輸入數字A:")
    a = input()
    print("請輸入數字B:")
    b = input()
    print("請輸入運算子:")
    c = input()
    opera = operationFactory.createOperation(c)
    opera.a = a
    opera.b = b
    opera.getResult()

在主函式中,operationFactory.createOperation方法可以根據你的輸入,獲取指定的運算物件。

然後通過指定的運算物件,呼叫其getResult()方法就可以獲取該類特有的運算結果。

優點:無論新增多少新的運算方式,只要使其重寫基類的抽象函式,再在工廠類中新增相應的分支程式碼,就可以獲取該類的特有運算結果。

缺點:新增新的運算類需要修改工廠方法,每次新增,工廠類都要重新打包編譯。

 

總結:

#一個實體類(包含抽象方法),實體類的實現類 (擴充套件類)

# 一個工廠類(用來根據不同需求例項化不同實現類)、

# 一個主函式

# 即通過工廠類獲取【基類的實現類】,然後呼叫【基類的實現類】的特定抽象方法,獲取對應結果

 

編碼中的小發現:

# 說起來python的類變數、突然想起來ptyhon中是否含有類的靜態變數這個東西。
# 然後就敲了下面的程式碼使其和C#程式碼進行對比。
# 對比發現,python和C#的一點點不同,python類裡面定義的變數,如果通過類名去改變,則所有的例項物件的變數都會受到影響。
# class demo():
#     a=10


# if __name__ == "__main__":
#     demoB = demo()
#     demoB.a = 1
#     demo.a = 100
#     demoA = demo()
#     demoB = demo()
#     print(demoA.a, demoB.a)

# 這裡輸出100,100


# if __name__ == "__main__":
#
#     demoA=demo()
#     demoA.a=100
#     demoB=demo()
#     print(demoA.a,demoB.a)
# 這裡輸出100,10

不對之處敬請指正!

相關文章