试图理解Python中的抽象工厂模式

时间:2017-01-31 04:12:37

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

我在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()

4 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:0)

使用抽象工厂模式,您可以生成特定Factory接口的实现,每个接口都知道如何创建不同类型的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?

答案 2 :(得分:0)

我没有阅读您的代码,也没有声称自己既不是Python方面的专家,也不是设计模式方面的专家。我会在可能有用的情况下给您一个用例,而不会声称它是这样做的正确/最佳方法:

想象一下,您有一个包含地理数据坐标的文件。 该文件中的对象包含各大洲,国家,州,市区等。 现在,对象类型的创建将恰好是动态的/在运行时, 因为您不能对新对象进行硬编码。

工厂将代替您自己创建新对象。 也许问题出在您对语言的理解之内,因为Python是一种与Java相反的动态类型化语言。

这并不意味着,一个要比另一个更好,而是在学习概念时, Python使启动起来更容易,而Java在以后的阶段中更容易理解问题(我知道...样板代码)。如果您有Java背景,请尝试在那里首先实现(我不敢相信我实际上是将其写下来的)。

希望这个简短的解释有帮助。

答案 3 :(得分:0)

我知道另一个解释更好的网站,也提供了许多不同编程语言(包括Python)中的示例代码。

https://refactoring.guru/design-patterns/abstract-factory/python/example#lang-features

玩得开心!