Python設計模式:工廠模式


工廠模式:“工廠”即表示一個負責創建其他類型的對象的類,通常情況下,一個工廠的對象會有一個或多個方法與之關聯,這些方法用於創建不同類型的對象,工廠對象會根據客戶端給方法傳遞的不同的參數或者客戶端調用不同的方法返回不同的對象。

優點:對象的創建是可以根據需要單獨創建的,但是使用工廠模式來創建對象有以下優點:

  • 松耦合,對象的創建是根據工廠類來進行的,與類本身的實現是獨立開來的。
  • 對於客戶端來說,不需要知道類的具體實現,只需要調用相應接口就可以得到需要的對象了,這其實是簡化了客戶端的相關實現。
  • 對於對象的修改只需要在工廠里面進行即可,包括添加新的對象,客戶端只需要更改少量的代碼,甚至可以不修改代碼就可以達到要求。
  • 使用工廠接口,還可以重用已有的對象,不用去別處調用已有的對象或者重新創建一個對象。

工廠模式的3種實現形式(或者說3中變體):

  • 簡單工廠模式:工廠類會提供一個接口,並根據客戶端傳入參數來創建相應的實例對象。(創建一個對象)
  • 工廠方法模式:需要定義一個基類,不同的子類則代表着不同類型的對象。相對於簡單工廠模式而言,工廠方法模式具有更強的可定制性。(創建一個對象)
  • 抽象工廠模式:需要定義一個抽象工廠類,然后由不同的子類來創建不同系列的對象,一個系列即代表一組對象。(創建一組對象)

簡單工廠模式示例:

from abc import ABCMeta, abstractmethod


class Flower(metaclass=ABCMeta):
    @abstractmethod
    def show_price(self):
        pass


class Rose(Flower):
    def show_price(self):
        print('Rose price: $99')


class Tulip(Flower):
    def show_price(self):
        print('Tulip price: $66')


class FlowerSimpleFactory:
    def get_flower(self, flower_type):
        return eval(flower_type)()


if __name__ == '__main__':
    flower_factory = FlowerSimpleFactory()
    rose = flower_factory.get_flower('Rose')
    tulip = flower_factory.get_flower('Tulip')
    rose.show_price()
    tulip.show_price()
Rose price: $99
Tulip price: $66

特點:接口根據客戶端傳入的參數即可返回對應的實例對象,甚至不用返回它的對象就可以進行對應的操作(比如示例中的工廠FlowerSimpleFactory中可以直接定義一個print_price方法來打印各種花的價格,而不是先返回對象,再由對象調用show_price方法來打印),即不會暴露對象的創建邏輯,客戶端直接使用接口即可完成對象的創建,甚至創建對象之后的一些操作。

 

工廠方法模式示例:

from abc import ABCMeta, abstractmethod


class Flower(metaclass=ABCMeta):
    @abstractmethod
    def show_price(self):
        pass


class Rose(Flower):
    def show_price(self):
        print('Rose price: $99')


class Tulip(Flower):
    def show_price(self):
        print('Tulip price: $66')


class Lily(Flower):
    def show_price(self):
        print('Lily price: $33')


class FlowerShopFactory(metaclass=ABCMeta):
    def __init__(self):
        self.flowers = []
        self.stock_flowers()

    @abstractmethod
    def stock_flowers(self):
        pass

    def get_flowers(self):
        return self.flowers

    def add_flower(self, flower):
        self.flowers.append(flower)


class FlowerShop1(FlowerShopFactory):
    def stock_flowers(self):
        self.add_flower(Rose())
        self.add_flower(Tulip())


class FlowerShop2(FlowerShopFactory):
    def stock_flowers(self):
        self.add_flower(Rose())
        self.add_flower(Tulip())
        self.add_flower(Lily())


if __name__ == '__main__':
    flower_shop1 = FlowerShop1()
    for flower in flower_shop1.get_flowers():
        flower.show_price()

    flower_shop2 = FlowerShop2()
    for flower in flower_shop2.get_flowers():
        flower.show_price()
Rose price: $99
Tulip price: $66
Rose price: $99
Tulip price: $66
Lily price: $33

特點:工廠方法可以根據基類來定義不同的子類,如示例中的FlowerShop1和FlowerShop2,每個子類則代表“工廠”可以創建的一個“產品”。即對象的創建是通過繼承的子類來完成的。

 

抽象工廠模式示例:

from abc import ABCMeta, abstractmethod


class MiniCar(metaclass=ABCMeta):
    @abstractmethod
    def show_size(self):
        pass


class SedanCar(metaclass=ABCMeta):
    @abstractmethod
    def show_price(self):
        pass


# 國產車
class DomesticMiniCar(MiniCar):
    def show_size(self):
        print('Domestic mini car size: 111')


class DomesticSedanCar(SedanCar):
    def show_price(self):
        print('Domestic sedan car price: 10W')


# 英國車
class EnglishMiniCar(MiniCar):
    def show_size(self):
        print('English mini car size: 222')
        

class EnglishSedanCar(SedanCar):
    def show_price(self):
        print('English sedan car price: 30w')


# 抽象工廠類
class CarFactory(metaclass=ABCMeta):
    @abstractmethod
    def create_mini_car(self):
        pass

    @abstractmethod
    def create_sedan_car(self):
        pass


# 國產車工廠類
class DomesticCarFactory(CarFactory):
    def create_mini_car(self):
        return DomesticMiniCar()
    
    def create_sedan_car(self):
        return DomesticSedanCar()


# 英國車
class EnglishCarFactory(CarFactory):
    def create_mini_car(self):
        return EnglishMiniCar()
    
    def create_sedan_car(self):
        return EnglishSedanCar()

 

特點:需要定義一個接口(如示例的抽象工廠類)來創建一系列的相關對象,如示例中的兩個子類分別創建兩個系列的對象(國產車和英國車),即對象的創建也是由子類來完成。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM