Today I would like to introduce a very simple design pattern, a learn, very easy to use.

This pattern is called the Abstract Factory pattern, which you may be familiar with, and encapsulates the instance creation logic in the factory pattern. The main purpose is to integrate the creation of complex classes, with parameter control, so that users can easily obtain instances.

The abstract factory

The Abstract factory pattern is similar to the factory pattern, but at a more abstract level. When an instance is created, it is not controlled by parameters, but by passing in the class you want to create. And this is actually a feature of Python, where everything is an object, everything can be passed as a parameter, and a class itself is an object, and a class can be passed as a parameter. So we can pass a class directly to the factory, and the factory creates instances from the class.

Let’s briefly demonstrate this in code:

class AbstractFactory:

    def __init__(self, cls):

        self.cls = cls

        

    def build(self, *args, **kw):

        return self.cls(*args, **kw)

Copy the code

You can see this code, but you can’t really call it an abstraction factory, because there’s no abstraction. The main abstraction here is to use the factory as a higher level abstract class, sort of the reverse of the abstract class.

This is how we typically use abstract classes:

import abc



class AbstractClass:

    def __init__(self):

        pass

    

@abc.abstractmethod

    def run(self, *args, **kw):

        pass

Copy the code

Its derived classes then implement the abstract methods defined in the abstract class, but the order is reversed. The logic in the parent class is also specified, but it is implemented by calling the instance of the passed child class.

To illustrate, let’s look at an example:

class PetCollection(object):



    def __init__(self, animal):

        self.pet_generator = animal

        self.pet = self.pet_generator()

    

    def speak(self):

        self.pet.speak()



    def show_pet(self):

        pet = self.pet

        print('Pet\'s name is {}'.format(pet))

        print('It says: {}! '.format(pet.speak()))





class Dog(object):

    def speak(self):

        return 'woof'



    def __str__(self):

        return 'dog'





class Cat(object):

    def speak(self):

        return 'meow'



    def __str__(self):

        return 'cat'



if __name__ == '__main__':

    pet = PetCollection(Dog)

    pet.show_pet()

Copy the code

In this example, Dog and Cat are subclasses, and PetCollection is the parent class. We can see that the parent class implements the speak method, but it calls the subclass’s Speak implementation. That is to say, any subclass with the speak class can be used to create PetCollection, which is equivalent to an abstract general class, so that we can use it to integrate a lot of logic and simplify operations.

When I first looked at this design pattern, it seemed generic, with classes as parameters. But after looking at it again, I realized that it was also a reverse use of abstract classes. In fact, the core of the code is only logic, the so-called design pattern is just a summary of previous experience. What is really valuable is not how the code of the pattern is written, but the core logic, and once these are understood, it is not difficult to design our own pattern.

That’s all for today’s article. I sincerely wish you all a fruitful day. If you still enjoyed today’s video, don’t forget the triple link.

This article was published on the public account TechFlow, asking for attention