設計模式之單例模式與工廠模式的Python實現(二) Python中的staticmethod與classmethod python中@classmethod @staticmethod區別

2. 工廠模式html

工廠模式是建立型設計模式的一種。核心的思想是,經過傳遞給類或函數某種產品的信息來建立產品並返回。當咱們想獲得產品a對象,只需把產品a的名字傳遞給工廠函數就能獲得產品a對象。而核心思想的背後是爲了遵循著名的「開閉原則」:對擴展開放,對修改封閉。當添加新功能時,對已經有的函數代碼不須要修改,只須要添加新功能相關的代碼便可。python

舉一個最簡單的例子:假如咱們要寫一個計算器,實現加減乘除四則運算,那麼最簡單的方法就是寫一個函數,傳入運算符,而後經過switch語句(python中沒有switch語句,能夠想辦法用字典dict代替)。但問題也是顯而易見的,若是咱們要添加一個新的運算,好比開平方,那麼就要修改原來的包含了四則運算的函數,顯然,在這個過程當中容易發生錯誤的修改,好比不當心改到了加法運算,這會讓咱們原先寫好的功能有被修改錯誤的風險。因此,對應到這個問題上,工廠模式的核心就是要把這幾個運算給徹底獨立出來,而且不影響運算主函數(即當添加新的運算時,咱們不須要修改運算主函數)。怎麼作呢?其實就是建立一個工廠類,由這個工廠類經過判斷傳入的運算符,去對應實例化各個運算函數(或者運算類)。這樣,當添加了新的運算時,咱們只須要添加新的運算函數(或者運算類),和修改工廠類(即添加新的switch判斷,實例化新的運算函數或者運算類)就能夠了。設計模式

2.1 簡單工廠模式函數

簡單工廠模式,是最簡單的工廠方法模式,其由兩部分組成,一是:工廠函數或工廠類,二是:產品類(能夠是多個產品類A,B,C.........)。post

下面咱們經過一個簡單的例子來看什麼是簡單工廠模式:url

class A(object):
    def __init__(self, product_type):
        self.product_type = product_type
 
    def __str__(self):
        return 'product %s' % self.product_type
 
 
class B(object):
    def __init__(self, product_type):
        self.product_type = product_type
 
    def __str__(self):
        return 'product %s' % self.product_type
 
 
class Factory(object):
    @staticmethod
    def yield_product(product_type):
        if product_type == 'A':
            return A(product_type)
        if product_type == 'B':
            return B(product_type)
 
if __name__ == '__main__':
    a = Factory.yield_product('A')
    b = Factory.yield_product('B')
    print(a)
    print(b)

結果以下spa

product A
product B

上面代碼中,實現了兩個產品類A,B,一個工廠類Factory,工廠類中實現了一個靜態方法,其實,能夠用一個工廠函數來代替這個工廠類。靜態方法能夠經過類名進行調用,而不需把類實例化。.net

靜態方法@staticmethod的意思是,這個方法是一個普通方法,雖然屬於類,可是不用訪問類的其餘成員。而且能夠在不把類實例化的前提下,經過類名進行調用設計

2.2 工廠方法模式code

簡單工廠模式存在一個問題,當要增長產品時,須要修改工廠類或者工廠方法,在上面的例子中,咱們須要修改工廠類的方法"yield_product"這違背了擴展開放,修改封閉的原則,所以是不可取的。工廠方法模式可以實現最小化地修改工廠類或工廠函數。

具體實現:對每個產品類再進行一次封裝,封裝成只生產特定產品的工廠類。

import abc
 
 
class A(object):
    def __init__(self, product_type):
        self.product_type = product_type
 
    def __str__(self):
        return 'product %s' % self.product_type
 
 
class B(object):
    def __init__(self, product_type):
        self.product_type = product_type
 
    def __str__(self):
        return 'product %s' % self.product_type
 
 
class Abstract_factory(object):
    __metaclass__ = abc.ABCMeta
 
    @abc.abstractmethod
    def yield_product(self):
        pass
 
 
class Factory_a(Abstract_factory):
 
    def yield_product(self):
        return A('A')
 
 
class Factory_b(Abstract_factory):
 
    def yield_product(self):
        return B('B')
 
 
def factory(product_type):
    if product_type == 'A':
        return Factory_a()
    if product_type == 'B':
        return Factory_b()
 
if __name__ == '__main__':
    factory_a = factory('A')
    a = factory_a.yield_product()
    factory_b = factory('B')
    b = factory_b.yield_product()
    print(a)
    print(b)

結果以下

product A
product B

上述代碼,Factory_a,Factory_b是對類A,B的封裝,一個工廠只負責建立一個產品聽從了單一職責原則,有利於代碼的擴展和維護。

其中@abc.abstractmethod表示被該裝飾器修飾的方法是一個抽象方法,沒有實現,因此該基本不能被實例化。只有子類實現了該抽象方法才能被實例化。

 

參考連接:

1. python 設計模式(三) 工廠模式 https://blog.csdn.net/ruguowoshiyu/article/details/80657052

2. Python中的staticmethod與classmethod

3. python中@classmethod @staticmethod區別

4. Python2和Python3中@abstractmethod的用法 https://blog.csdn.net/xiemanR/article/details/72629164

相關文章
相關標籤/搜索