1. 程式人生 > >python 設計模式(三) 工廠模式

python 設計模式(三) 工廠模式

工廠模式是建立型設計模式的一種。核心的思想是,通過傳遞給類或函式某種產品的資訊來建立產品並返回。當我們想得到產品a物件,只需把產品a的名字傳遞給工廠函式就能得到產品a物件。

1 簡單工廠方法模式

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

程式碼如下:

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)

結果如下

product A
product B

上面程式碼中,實現了兩個產品類A,B,一個工廠類Factory,工廠類中實現了一個靜態方法,其實,可以用一個工廠函式來代替這個工廠類。靜態方法可以通過類名進行呼叫,而不需把類例項化

2 工廠方法模式

簡單工廠模式存在一個問題,當要增加產品時,需要修改工廠類或者工廠方法,這違背了擴充套件開放,修改封閉的原則,因此是不可取的。工廠方法模式能夠實現最小化地修改工廠類或工廠函式。

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

程式碼如下:

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的封裝,一個工廠只負責建立一個產品遵從了單一職責原則,有利於程式碼的擴充套件和維護。

3 抽象工廠模式

對於複雜的問題,工廠方法模式會實現很多工廠類,不利於程式碼維護,因此要用到抽象工廠模式

程式碼如下

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_a(self):
        pass
    def yield_product_b(self):
        pass


class Factory_1(Abstract_factory):

    def yield_product_a(self):
        return A('A')

    def yield_product_b(self):
        return B('B')


class Factory_2(Abstract_factory):
    def yield_product_a(self):
        return A('A')

    def yield_product_b(self):
        return B('B')


def factory(product_type):
    if product_type == '1':
        return Factory_1()


if __name__ == '__main__':
    factory_1 = factory('1')
    a = factory_1.yield_product_a()
    b = factory_1.yield_product_b()
    print(a)
    print(b)

product A
product B

上述程式碼,Abstract_factory類實現了兩個抽象方法,生產產品a和生產產品b。工廠1負責這兩個產品的生產,之所以把兩個產品放在同一個工廠中,是因為有些複雜的職責是由兩個產品來完成的。

什麼時候使用抽象工廠呢,通常剛開始使用工廠方法模式,當發現應用需要很多工廠方法時,可以將建立一系列物件的過程合併到一起,從而引入抽象工廠模式