6

I found this example of abstract factory pattern in Python. I'm trying to make sense of why there needs to be a DogFactory, wouldn't it be lesser code just call the Dog class, can someone explain as to how this pattern will be useful in a real world application

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()
teddybear123
  • 2,314
  • 6
  • 24
  • 38

2 Answers2

3

There are two main benefits of the Abstract Factory pattern:

1) Decouple the client code

The point of the Abstract Factory pattern is to decouple the client (in this case PetStore) from the concrete classes it creates (in this case Dog).

Image you had a different family of pets - cats, for example. Using the Abstract factory pattern, you can create a different factory that produces Cat objects. The key insight here is that both factories share the same interface - i.e. get_pet() and 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!"

Now, because of the common interface between factories, you only need to chance one line of code to have the client act on cats instead of dogs:

factory = CatFactory()

The PetStore class itself does not need to be changed.

2) Enforce a relationship between a family of related classes

You could argue that, instead of passing in a DogFactory or CatFactory, why not just pass in a Dog or a Cat? And this is where your example code fails to show the power of the Abstract Factory pattern. The pattern really shines when there is a whole family of related classes that go together. In your example, there is only the dog itself, and the dog food. But imagine you also had a dog bed, a dog collar, a dog toy, etc. If this were the case, and you were not using the Abstract Factory pattern, then you might write code like this:

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

shop = PetStore(pet, food, bed, collar, toy)

This code is verbose and inflexible. There also is a danger that you might accidentally pass a cat toy in with dog products.

Instead, using an AbstractFactory, the code becomes trivial and the relationship between the families of classes is enforced:

factory = DogFactory()
shop = PetStore(factory)  # PetStore calls get_*(), and is guaranteed
                          # to only get dog products
Lee Netherton
  • 21,347
  • 12
  • 68
  • 102
  • Since Python classes are already factories for their instances, how do explicit factories provide a benefit? There seems to be no advantage in using ``CatFactory().get_pet`` over just ``Cat``. – MisterMiyagi Jan 10 '21 at 12:57
  • @MisterMiyagi. If you are just instantiating a pet, then I agree, there is no advantage (so point 1 is probably irrelevant in python). However, point 2 still stands; if you are instantiating a family of related classes, then a factory class strengthens the relationship between these related classes. – Lee Netherton Jan 10 '21 at 18:08
0

With the Abstract Factory pattern, you produce implementations of a particular Factory interface, each of those knows how to create different a different kind of dog(). The methods of an Abstract Factory are implemented as Factory Methods. Both the Abstract Factory Pattern and the Factory Method Pattern decouples the client system from the actual implementation classes through the abstract types and factories.

See these reference links:-

  1. http://www.dofactory.com/net/abstract-factory-design-pattern#_self2
  2. What is the basic difference between the Factory and Abstract Factory Patterns?
Community
  • 1
  • 1
Plankton
  • 388
  • 3
  • 13
  • Unfortunately, the top answers in that SO thread are horribly wrong. Fortunately, there are better threads. [Differences between Abstract Factory Pattern and Factory Method](https://stackoverflow.com/questions/5739611/differences-between-abstract-factory-pattern-and-factory-method/50786084#50786084). – jaco0646 Nov 08 '18 at 14:09