【问题标题】:trying to make sense of abstract factory pattern in Python试图理解 Python 中的抽象工厂模式
【发布时间】:2017-01-31 04:12:37
【问题描述】:

我在 Python 中找到了这个抽象工厂模式的示例。我试图弄明白为什么需要一个 DogFactory,难道只是调用 Dog 类的代码更简单吗?有人可以解释一下这种模式在现实世界的应用程序中如何有用

class Dog:

    def speak(self):
        return "Woof!"

    def __str__(self):
        return "Dog"


class DogFactory:

    def get_pet(self):
        return Dog()

    def get_food(self):
        return "Dog Food!"


class PetStore:

    def __init__(self, pet_factory=None):

        self._pet_factory = pet_factory


    def show_pet(self):

        pet = self._pet_factory.get_pet()
        pet_food = self._pet_factory.get_food()

        print("Our pet is '{}'!".format(pet))
        print("Our pet says hello by '{}'".format(pet.speak()))
        print("Its food is '{}'!".format(pet_food))

factory = DogFactory()

shop = PetStore(factory)

shop.show_pet()

【问题讨论】:

    标签: python python-2.7 design-patterns abstract-factory


    【解决方案1】:

    抽象工厂模式有两个主要好处:

    1) 解耦客户端代码

    抽象工厂模式的重点是将客户端(在本例中为 PetStore)与其创建的具体类(在本例中为 Dog)解耦。

    图片您有不同的宠物家庭 - 例如猫。使用抽象工厂模式,您可以创建一个不同的工厂来生成Cat 对象。这里的关键见解是两个工厂共享相同的接口 - 即 get_pet()get_food()

    class Cat:
        def speak(self): return "Meow!"
        def __str__(self): return "Cat"
    
    class CatFactory:
        def get_pet(self): return Cat()
        def get_food(self): return "Cat Food!"
    

    现在,由于工厂之间的通用接口,您只需要偶然的一行代码就可以让客户端对猫而不是狗进行操作:

    factory = CatFactory()
    

    PetStore 类本身不需要更改。

    2) 强制一系列相关类之间的关系

    您可能会争辩说,与其传递DogFactoryCatFactory,不如直接传递DogCat?这就是您的示例代码未能展示抽象工厂模式强大功能的地方。当整个系列的相关类一起出现时,这种模式真的会发光。在您的示例中,只有狗本身和狗粮。但是假设你还有一张狗床、一个狗项圈、一个狗玩具等。如果是这样,并且你没有使用抽象工厂模式,那么你可能会编写如下代码:

    pet = Dog()
    food = DogFood()
    bed = DogBed()
    collar = DogCollar()
    toy = DogToy()
    
    shop = PetStore(pet, food, bed, collar, toy)
    

    此代码冗长且不灵活。还有一种危险,您可能会不小心将猫玩具和狗制品一起送进去。

    相反,使用 AbstractFactory,代码变得微不足道,并且类家族之间的关系被强制执行:

    factory = DogFactory()
    shop = PetStore(factory)  # PetStore calls get_*(), and is guaranteed
                              # to only get dog products
    

    【讨论】:

    • 既然 Python 类已经是它们实例的工厂,那么显式工厂如何提供好处呢?使用CatFactory().get_pet 似乎比仅使用Cat 没有优势。
    • @MisterMiyagi。如果您只是实例化宠物,那么我同意,没有任何优势(因此第 1 点在 python 中可能无关紧要)。但是,第 2 点仍然有效;如果您要实例化一系列相关类,那么工厂类会加强这些相关类之间的关系。
    【解决方案2】:

    使用抽象工厂模式,您可以生成特定工厂接口的实现,每个接口都知道如何创建不同类型的 dog()。抽象工厂的方法被实现为工厂方法。抽象工厂模式和工厂方法模式都通过抽象类型和工厂将客户端系统与实际实现类解耦。

    查看这些参考链接:-

    1. http://www.dofactory.com/net/abstract-factory-design-pattern#_self2
    2. What is the basic difference between the Factory and Abstract Factory Patterns?

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-08
    • 2010-09-06
    • 1970-01-01
    相关资源
    最近更新 更多