[design pattern learning notes] detailed explanation of simple factory pattern, factory pattern and abstract factory pattern cases (C + + implementation)

catalogue

1, Simple factory mode

1. What is the simple factory model

2. Example of simple factory mode

3. Advantages and disadvantages of simple factory mode

II. Factory mode

1. What is the factory model

2. Example of factory mode

3. Comparison between simple factory and factory mode

III. abstract factory model

1. What is the abstract factory pattern

2. Abstract factory pattern instance

3. Summary of abstract factory class

1, Simple factory mode

1. What is the simple factory model

Simple Factory Pattern, which is also called static factory method pattern. It belongs to a kind of creative design pattern of classes. A special class (factory) is responsible for creating instances (specific products) of other classes. These classes have a common abstract class as the base class (Abstract products).

Three roles in the simple factory model

  1. Factory role: Creator, which is used to create all specific product instances. It is the core of the simple factory model. The factory class is directly called externally and provides a static method to create instances of different product classes according to different parameters.
  2. Abstract Product role: Product, which is the common base class of all instance classes created by the factory class. It is used to describe the public interface of the Product. It is dependent on the factory class (as the return value of the static method of the factory class).
  3. Specific product role: Concrete Product, which is a subclass of the abstract product class and the target class to be created by the factory class.

2. Example of simple factory mode

Suppose we want to produce a mobile phone, including apple mobile phone and Xiaomi mobile phone. First, we should define an abstract product class PhoneInterface

//Abstract product class
class PhoneInterface
{
public:
	virtual void print_brand() = 0;
};

Then implement the specific product class according to the abstract product class. Suppose we have apple mobile phone and Xiaomi mobile phone

//Specific product category
class apple : public PhoneInterface
{
public:
	virtual void print_brand()
	{
		cout << "iPhone" << endl;
	}
};


class XiaoMi : public PhoneInterface
{
public:
	virtual void print_brand()
	{
		cout << "Mi phones" << endl;
	}
};

Next, you should create a factory class, which defines the logic of creating all product class instances and the judgment of which product class instance to create.

//Factory class
class Factory
{
public:
	PhoneInterface* production_phone(int flag)
	{
		PhoneInterface* pTemp = NULL;
		switch (flag) //All production is concentrated in one factory, and each modification must be modified in the class, which does not comply with the opening and closing principle
		{
		case 1:
			pTemp = new apple;
			break;
		case 2:
			pTemp = new XiaoMi;
			break;
		default:
			pTemp = NULL;
			break;
		}
		return pTemp;
	}
};

In this way, customers can produce the mobile phones they need through factories, and can successfully complete the production of mobile phone models.

int main()
{
	Factory* pF = NULL;
	PhoneInterface* pPhone = NULL;

	pF = new Factory;
	pPhone = pF->production_phone(1);
	pPhone->print_brand();
	delete pPhone;
	
	pPhone = pF->production_phone(2);
	pPhone->print_brand();
	delete pF;
	delete pPhone;

	system("pause");
	return 0;
}

3. Advantages and disadvantages of simple factory mode

Advantages: the factory class is the core of the whole simple factory mode. The factory class hides the specific details of creating an instance. Users directly use the factory class to create the instance they need, without caring about how the instance is created or how the internal structure is organized.

Disadvantages: the advantages of the simple factory mode come from the factory class, and its disadvantages also come from the factory class, because the creation logic of all instances is concentrated in the factory class. Once there is a problem in the factory, the creation of all instances will not be possible, and the addition and deletion of products will be realized by modifying the factory class, which does not comply with the opening and closing principle. Because the simple factory mode does not comply with the opening and closing principle, it is not a standard design mode.

II. Factory mode

1. What is the factory model

Factory pattern, which also belongs to the creation pattern of class, has also become a polymorphic factory pattern. The factory mode corrects the defect that the simple factory mode does not comply with the opening and closing principle. The factory mode has an abstract factory role as an interface, and the actual production work is implemented in the specific factory class. This further abstraction makes the factory method mode enable the system to introduce new products without modifying the specific factory role. In short, it is to subdivide the factories in a simple factory into factories with different products, and each factory produces one product.

  1. Abstract factory role (Creator). All concrete factories should implement this interface;
  2. Concrete creator is responsible for instantiating specific product objects;
  3. Abstract role (Product), like the simple factory pattern, is the common base class of all instance classes created by the factory class, which is used to describe the public interface of the product.
  4. Concrete product role refers to the object to be instantiated by the specific factory class.

2. Example of factory mode

Abstract product classes and concrete product classes remain unchanged

//Abstract product class
class PhoneInterface
{
public:
	virtual void print_brand() = 0;
};

//Apple mobile product realization
class apple : public PhoneInterface
{
public:
	virtual void print_brand()
	{
		cout << "iPhone" << endl;
	}
};

//Implementation of Xiaomi mobile phone products
class XiaoMi : public PhoneInterface
{
public:
	virtual void print_brand()
	{
		cout << "Mi phones" << endl;
	}
};

Firstly, an abstract factory class is defined to define the unified interface of specific factories

//Abstract factory class
class FactoryInterface
{
public:
	virtual PhoneInterface* production_phone() = 0;
};

Then define an apple mobile phone factory to produce apple mobile phones, and then define a Xiaomi mobile phone factory to produce apple mobile phones. Then these two factories are the specific factory roles

//Apple mobile phone factory
class AppleFactory : public FactoryInterface
{
public:
	virtual PhoneInterface* production_phone()
	{
		return new apple;
	}
};

//Xiaomi mobile phone factory
class XiaomiFactory : public FactoryInterface
{
public:
	virtual PhoneInterface* production_phone()
	{
		return new XiaoMi;
	}
};

When we need to produce mobile phone products, we can directly use Apple mobile phone factory to create Apple mobile phone objects and Xiaomi mobile phone factory to create Xiaomi mobile phone objects. If we increase demand and need Huawei mobile phones, then we only need to add an implementation class of Huawei factory and Huawei mobile phones. The abstract classes of factory and mobile phones do not need to be moved, which conforms to the opening and closing principle.

int main()
{
	FactoryInterface* pFactory = NULL;
	PhoneInterface* pPhone = NULL;

	//To produce an Apple phone
	//First create an Apple phone factory
	pFactory = new AppleFactory;
	pPhone = pFactory->production_phone();
	pPhone->print_brand();
	delete pPhone;
	delete pFactory;

	//Produce a Xiaomi mobile phone
	pFactory = new XiaomiFactory;
	pPhone = pFactory->production_phone();
	pPhone->print_brand();
	delete pPhone;
	delete pFactory;

	system("pause");
	return 0;
}

3. Comparison between simple factory and factory mode

The simple factory mode puts all the creation logic into a factory class, while the factory mode provides an abstract factory interface for specific factories to create product instances, which greatly facilitates the operations of adding and deleting products, and well conforms to the opening and closing principle. The factory class must be modified directly every time a product is added or deleted in the simple factory mode, The factory mode only needs to add a specific factory class and a specific product class to complete the function expansion.

In the simple factory mode, the client is programmed for specific factories, and the code should be modified in the factory class to add products; The factory pattern is oriented to abstract factory programming. To add products, just create a new concrete factory, which is oriented to abstract class programming.

III. abstract factory model

1. What is the abstract factory pattern

Abstract Factory Pattern, Abstract Factory Pattern. Assuming that under the previous factory mode, we put forward further requirements for the product line. Because mobile phones should be sold both at home and abroad, the same brand mobile phones have added product lines such as mainland version, American version and Hong Kong version. If the factory mode is used, each brand of mobile phone and each version of mobile phone should be created in a separate specific factory, which is very inconvenient. "At this time, there is the abstract factory mode, which can create a product family (including multiple product lines). The Abstract Factory Pattern described in official language is a pattern structure that provides an interface for the access class to create a group of related or interdependent objects, and the access class can obtain different levels of products of the same family without specifying the specific class of the product. She also has four roles, just like the factory model.

  1. Abstract factory role (Creator). All concrete factories need to implement this interface, which can create multiple products of different levels (multiple product lines);
  2. Concrete creator is responsible for instantiating specific product objects and multiple product lines;
  3. Abstract role (Product), like the simple factory pattern, is the common base class of all instance classes created by the factory class, which is used to describe the public interface of the product.
  4. Concrete product role refers to the object to be instantiated by the specific factory class.

2. Abstract factory pattern instance

First, create an abstract mobile phone class

//Abstract product
class PhoneInterface
{
public:
	virtual void print_brand() = 0;
};

According to the definition of abstract mobile phone category, the mainland version of Apple mobile phone category, the US version of Apple mobile phone category, the mainland version of Xiaomi mobile phone category and the US version of Xiaomi mobile phone category

//American version of Apple mobile phone
class UsApple : public PhoneInterface
{
public:
	virtual void print_brand()
	{
		cout << "American version of Apple mobile phone" << endl;
	}
};

//Mainland Xiaomi mobile phone
class ChinaXiaomi : public PhoneInterface
{
public:
	virtual void print_brand()
	{
		cout << "Mainland version of Xiaomi mobile phone" << endl;
	}
};

//US version of Xiaomi mobile phone
class UsXiaomi : public PhoneInterface
{
public:
	virtual void print_brand()
	{
		cout << "US version of Xiaomi mobile phone" << endl;
	}
};

Next, define an abstract factory class, which contains two interfaces, one is apple mobile phone production line and the other is Xiaomi mobile phone production line

//Abstract factory
class FactoryInterface
{
public:
	//Product line 1: Apple mobile phone
	virtual PhoneInterface* production_apple() = 0;
	//Product line 2: Xiaomi mobile phone
	virtual PhoneInterface* production_xiaomi() = 0;
};

Two concrete factories are defined according to the abstract factory, one is the mainland mobile phone factory and the other is the American mobile phone factory

//Factories producing mainland version mobile phones
class ChinaFactory : public FactoryInterface
{
public:
	//Product line 1: Apple mobile phone
	virtual PhoneInterface* production_apple()
	{
		return new ChinaApple;
	}
	//Product line 2: Xiaomi mobile phone
	virtual PhoneInterface* production_xiaomi()
	{
		return new ChinaXiaomi;
	}
};

//A factory that produces American mobile phones
class UsFactory : public FactoryInterface
{
public:
	//Product line 1: Apple mobile phone
	virtual PhoneInterface* production_apple()
	{
		return new UsApple;
	}
	//Product line 2: Xiaomi mobile phone
	virtual PhoneInterface* production_xiaomi()
	{
		return new UsXiaomi;
	}
};

Customers can directly use two specific factories to produce continental apple / Xiaomi mobile phones or American apple / Xiaomi mobile phones

int main()
{
	FactoryInterface* pFactory = NULL;
	PhoneInterface* pPhone = NULL;

	//Factories using mainland mobile phones
	cout << "======Mainland mobile phone factory======" << endl;
	pFactory = new ChinaFactory;
	//Production of mainland Apple mobile phone
	pPhone = pFactory->production_apple();
	pPhone->print_brand();
	delete pPhone;
	//Production of mainland Xiaomi mobile phone
	pPhone = pFactory->production_xiaomi();
	pPhone->print_brand();
	delete pPhone;
	delete pFactory;

	//Factories using American mobile phones
	cout << "======American mobile phone factory======" << endl;
	pFactory = new UsFactory;
	pPhone = pFactory->production_apple();
	pPhone->print_brand();
	delete pPhone;
	pPhone = pFactory->production_xiaomi();
	pPhone->print_brand();
	delete pPhone;
	delete pFactory;

	system("pause");
	return 0;
}

3. Summary of abstract factory class

When adding a new product family, you only need to add a new specific factory. If the whole product family has only one level of products, such as only one production line, the abstract factory is the same as the factory mode.

Tags: C++ Design Pattern

Posted by mart on Sat, 16 Apr 2022 08:11:35 +0930