(Creation mode) Design mode-factory, abstract factory C++/Python3 implementation

Posted Jun 26, 20205 min read

Introduction

The design pattern is a solution designed to solve some emerging problems. It is a summary of long-term experience, which is a solution proposed and practiced according to different problems. Using different design patterns can solve different problems.
Design patterns can be divided into three major categories:creational patterns, structural patterns, and behavioral patterns.

In the development, assuming that the design pattern is not used, it may cause excessive coupling, will cause a certain amount of code redundancy, and may affect the subsequent development process; reasonable use of suitable design patterns will increase overall flexibility and reduce Subsequent maintenance costs.

The creation mode, as the name suggests, is a design mode that deals with object creation, reduces complexity, and is used when creating complex objects.

Factory mode

Implement an interface in the class to create the specified object, delaying the instantiation of a class to subclasses. To put it simply, the creation of the class is encapsulated. It only needs to call a subclass method to achieve the creation of the class, and does not expose the logic of creating the class.

The following is an example of a factory class:
The python code is as follows:

#ORIGINAL is not easy to support
#Blog:https://me.csdn.net/A757291228
class Factory:
    def getFruit(self, name, color, taste):
        if name =='apple':
            return Apple(color,taste)

class Fruit:
    def __init__(self):
        print("Fruit initialization")

    def get_color(self):
        return self.color

    def get_taste(self):
        return self.taste


class Apple(Fruit):
    def __init__(self, color, taste):
        print("Apple initialization")
        self.color = color
        self.taste = taste


class Banana(Fruit):
    def __init__(self, color, taste):
        print("Banana initialization")
        self.color = color
        self.taste = taste


if __name__ =='__main__':
    factory = Factory()
    appleClass = factory.getFruit("apple", "green", "sweet")
    print('Apple's color', appleClass.get_color(),'Apple's taste', appleClass.get_taste())

The C++ code is as follows:

//Original is not easy, support a lot
//Blog:https://me.csdn.net/A757291228

#include <iostream>
using namespace std;


class Fruit {
    public:
        string color;
        string taste;

        Fruit() {
        }
};

class Apple:public Fruit {
    public:
        Apple(string color, string taste) {
            this->color = color;
            this->taste = taste;
            cout << "Apple Class Creation"<< endl;
        }
};

class Factory {
    public:
        Fruit* getFruit(string name, string color, string taste)
        {
            if(name == "apple") {
                return new Apple(color, taste);
            }
        }
};

int main(){
    Factory* factory = new Factory();
    Fruit* apple=factory->getFruit("apple", "red", "sweet");
    cout << "The taste of apple"<< apple ->color<< endl;
}

It can be seen from the above code examples that each time you create a new class, you only need to know the specific label or specific name of the class, and you don t need to care about the implementation logic of the class, which reduces the code redundancy and the duplication to a certain extent. Work; However, there is also a problem exposed:Every time a new class is added, the logic needs to be implemented in the factory class, and the coupling between them is also enhanced. All the classes are created to a factory. When there are many types of your class, your code will look bloated, so the design pattern needs to consider whether the current project requirements meet this pattern before using it.

Abstract factory pattern

A single factory to create all types of classes would appear to be bloated, so wouldn t it be ok to create multiple factories? Every factory does a kind of thing. Just like working, there are front-end and back-end, UI, and operation and maintenance. Everyone divides work and cooperation, so it is very conditioning.

Abstract Factory solves this problem very well. The following is the sample code of the abstract factory.
The following code adds drawing from the above example code;

According to the above code modification, we define several food base Food; define several other categories, such as fruit, staple food and vegetables, which are several different categories of food. Set up three factories to process different foods, so that you don t have to worry about putting all factories in one factory for processing, and finally define an abstract factory class. This class encapsulates all factories in a unified way. Implemented the abstract factory class.

Python code:

#Abstract factory, main factory
#Original is not easy, support a lot
#Blog:https://me.csdn.net/A757291228
class MainFactory:
    def getFactory(self,factory_name):
        if factory_name=='Fruit':
            return FruitFactory()
        elif factory_name=='Vegetables':
            return VegetablesFactory()
        elif factory_name=='Staple':
            return StapleFactory()
#Factory class
class FruitFactory:
    def getFruit(self, name, color, taste):
        if name =='apple':
            return Apple(color,taste)
class VegetablesFactory:
    def getFruit(self, name, color, taste):
        if name =='carrot':
            return Carrot(color,taste)
class StapleFactory:
    def getFruit(self, name, color, taste):
        if name =='rice':
            return Rice(color,taste)

#Food base class
class Food:
    def __init__(self, taste):
        print("Food class initialization")
        self.taste = taste
#Fruit staple food and vegetables three base categories
class Fruit(Food):
    def __init__(self):
        print("Fruit initialization")

    def get_color(self):
        return self.color

    def get_taste(self):
        return self.taste

class Vegetables(Food):
    def __init__(self):
        print("Vegetable initialization")

    def get_color(self):
        return self.color

    def get_taste(self):
        return self.taste

class Staple(Food):
    def __init__(self):
        print("Initialization of staple food class")

    def get_color(self):
        return self.color

    def get_taste(self):
        return self.taste
#Specific category
class Apple(Fruit):
    def __init__(self, color, taste):
        print("Apple initialization")
        self.color = color
        self.taste = taste
class Rice(Staple):
    def __init__(self, color, taste):
        print("Initialization of rice")
        self.color = color
        self.taste = taste

class Carrot(Vegetables):
    def __init__(self, color, taste):
        print("Carrot initialization")
        self.color = color
        self.taste = taste


if __name__ =='__main__':
    mainFactory = MainFactory()
    fruitFactory=mainFactory.getFactory('Fruit')
    apple=fruitFactory.getFruit("apple", "green", "sweet")
    print('Apple's color:',apple.color,'Apple's taste:',apple.taste)

C++ implementation:

#include <iostream>
using namespace std;
//Original is not easy, support a lot
//Blog:https://me.csdn.net/A757291228

//Food base class
class Food {
public:
    string color;
    string taste;
    Food() {
    }
};

//Three categories
class Fruit :public Food {
public:
    Fruit() {
    }
};

class Vegetables :public Food {
public:
    Vegetables() {
    }
};

class Staple :public Food {
public:
    Staple() {
    }
};
//Three concrete classes
class Apple:public Fruit {
public:
    Apple(string color, string taste) {
        this->color = color;
        this->taste = taste;
        cout << "Apple class creation" << endl;
    }
};

class Rice:public Staple {
public:
    Rice(string color, string taste) {
        this->color = color;
        this->taste = taste;
        cout << "Apple class creation" << endl;
    }
};

class Carrot:public Vegetables {
public:
    Carrot(string color, string taste) {
        this->color = color;
        this->taste = taste;
        cout << "Apple class creation" << endl;
    }
};

//Factory base class
class Factory {
public:
    virtual Food* getFood()
    {
    }
};
//Specific factory class
class FruitFactory {
public:
    Food* getFood(string name, string color, string taste)
    {
        if(name == "apple") {
            return new Apple(color, taste);
        }
    }
};
class StapleFactory {
public:
    Food* getFood(string name, string color, string taste)
    {
        if(name == "apple") {
            return new Apple(color, taste);
        }
    }
};
class VegetablesFactory {
public:
    Fruit* getFood(string name, string color, string taste)
    {
        if(name == "apple") {
            return new Apple(color, taste);
        }
    }
};
//Main factory, abstract factory
class MainFactory {
public:
    FruitFactory* getFactory(string factory_name)
    {
        if(factory_name == "Fruit") {
            return new FruitFactory();
        }
    }
};

int main() {
    MainFactory* main_factory = new MainFactory();
    FruitFactory* fruit = main_factory->getFactory("Fruit");
    Food* apple = fruit->getFood("apple", "red", "sweet");
    cout << "The taste of apple" << apple->taste << endl;
}

The above code has passed the abstract factory to make unified factory calls with different attributes, enhancing the logic and structure.

Seeing here, I like it~(This is to add C# and Java, I don t have any trouble writing it, I will fill it later when I have time)