Creative mode - Factory mode (simple factory mode, factory method mode, abstract factory mode)

Posted by revez2002 on Thu, 28 Oct 2021 19:37:13 +0200

Statement: This blog refers to the Chinese Language C website: C Language Chinese Network Connection

The main record is learning the following:
1. Simple Factory Mode
II. Factory Method Mode
3. Abstract Factory Mode
Each main point consists of the following two parts:
(1) Basic concepts and model structure (including some NOUN explanations, model structure analysis (interception of Chinese web in C language)
(2) Sample code (including code, model analysis of code, analysis of model advantages and disadvantages)

Definition of factory mode: Defines a factory interface for creating product objects, placing the actual creation of product objects in a specific subfactory class. This meets the "Separate Creation from Use" feature required in the Creative Mode.

There are three different implementations of factory mode according to the actual business scenario, namely simple factory mode, factory method mode, and abstract factory mode.

1. Simple Factory Mode

1. Basic concepts and model structure

We refer to the object created as a "product" and the object created as a "factory". If you don't have many products to create, just one factory class can do it. This is called the Simple Factory Mode.

Simple factory mode has a specific factory class that can produce many different products, belonging to the creation design mode.

For each additional product in the simple factory model, a specific product class is added to modify and expand the original specific factory class, which increases the complexity of the system and violates the Open and Close Principle. As you can see in the code example below

Model structure:
Abstract Product: A parent class of all objects created by a simple factory that describes the common interfaces common to all instances.
Specific product: is the goal of creating a simple factory model.
Simple Factory: The core of the Simple Factory pattern, responsible for implementing the internal logic for creating all instances. The method of creating a product class for a factory class can be called directly from the outside world to create the desired product object.

2. Code samples and models

//Simple Factory Mode

enum TeaKind { tgy = 0, lj, dhp };
class DrinkBase //Abstract parent of a specific product
{
public:
	virtual ~DrinkBase() {}
	virtual void make() = 0;
};

class tgyTea :public DrinkBase //Specific Product 1
{
public:
	void make()
	{
		cout << "Making Tie Guanyin Tea!" << endl;
	}
};

class ljTea :public DrinkBase//Specific Product 2
{
public:
	void make()
	{
		cout << "Making a Longjing tea!" << endl;
	}
};

class dhpTea :public DrinkBase//Specific Product 3
{
public:
	void make()
	{
		cout << "Making a red gown tea!" << endl;
	}
};

class SimpleFactory //Factory Class
{
public:
	DrinkBase* MakeTea(TeaKind kind)//Establish
	{
		switch (kind)
		{
		case(lj):
			return new ljTea();
			break;
		case(dhp):
			return new dhpTea();
			break;
		case(tgy):
			return new tgyTea();
			break;
		default:
			break;
		}
		return nullptr;
	}
};

int main()
{
	//MakeTea methods can be set to static methods, accessed by class names, and do not require the creation of factory objects. This is used to create a factory object
	SimpleFactory factory;//Create a factory

	DrinkBase* li_ptr = factory.MakeTea(lj);//Making Longjing Tea in a Factory
	li_ptr->make();

	DrinkBase* dhp_ptr = factory.MakeTea(dhp);//Making red gown tea with factory
	dhp_ptr->make();

	DrinkBase* tgy_ptr = factory.MakeTea(tgy);//Making Tieguanyin Tea with Factory
	tgy_ptr->make();
	
	delete li_ptr;
	delete dhp_ptr;
	delete tgy_ptr;

	return 0;
}

(The example of design pattern in C language Chinese net is java, which explains how to use design pattern. Setting classes and methods to static makes it impossible to instantiate objects with classes, but I tried to find that static classes do not seem to work in C++, that is, adding classes without static in C++ is no different from the original use of classes.)
Run result:

Model:

In fact, we can find that there are many problems with the simple factory mode. The most serious one is that it violates the open and close principle. In addition, we can pick out other problems to see the evaluation of the simple factory mode in the C language Chinese network:
Merits and demerits
Advantage:
(1) The factory class contains the necessary logical judgment to decide when and which product instance to create. Clients can be exempted from the responsibility of directly creating product objects and create corresponding products easily. There is a clear division of responsibilities between the factory and the product.
(2) The client does not need to know the class name of the specific product being created, only the parameters.
Disadvantages:
(1) Simple factory mode has a single factory class, responsible for the creation of all products, overburdened with responsibilities, and the whole system will be affected if an exception occurs. And factory class codes can be very bulky, violating the principle of high aggregation.
(2) Using the simple factory mode increases the number of classes in the system (introducing new factory classes), increases the complexity and difficulty of understanding the system.
(3) It is difficult to expand the system. Once new products are added and the factory logic has to be modified, the logic may become too complex when there are many types of products.
(4) The simple factory model uses the static factory method, which prevents the factory roles from forming an inheritance-based hierarchy.
Application Scenarios
Consider using the simple factory model when there are relatively few product types. Clients using the simple factory mode can easily create the desired product by simply passing in parameters from the factory class and not caring about the logic of how the object is created.

II. Factory Method Mode

1. Basic concepts and model structure

The structure of the pattern:
The main roles of the factory method pattern are as follows.
Abstract Factory: Provides an interface for creating a product through which callers access the factory method newProduct() of a specific factory to create a product.
Specific factory: It mainly implements abstract methods in abstract factory to complete the creation of specific products.
Abstract product: Defines the specification of the product, describes the main features and functions of the product.
Specific products: Implements interfaces defined by abstract product roles, created by specific factories, which correspond one-to-one with specific factories.
Model structure:

2. Code samples and models

class DrinkBase //Abstract product class
{
public:
	virtual ~DrinkBase() {}
	virtual void make() = 0;
};

class tgyTea :public DrinkBase //Specific Product 1
{
public:
	void make()
	{
		cout << "Making Tie Guanyin Tea!" << endl;
	}
};

class ljTea :public DrinkBase//Specific Product 2
{
public:
	void make()
	{
		cout << "Making a Longjing tea!" << endl;
	}
};

class dhpTea :public DrinkBase//Specific Product 3
{
public:
	void make()
	{
		cout << "Making a red gown tea!" << endl;
	}

};

class FactoryBase //Abstract factory class
{
public:
	virtual DrinkBase* TeaMake() = 0;
};

class Factory_lj :public FactoryBase //Specific Factory 1
{
public:
	DrinkBase* TeaMake()
	{
		return new ljTea();
	}
};

class Factory_tgy :public FactoryBase //Specific Factory 2
{
public:
	DrinkBase* TeaMake()
	{
		return new tgyTea();
	}
};

class Factory_dhp :public FactoryBase //Specific Factory 3
{
public:
	DrinkBase* TeaMake()
	{
		return new dhpTea;
	}
};


int main()
{
	Factory_dhp dhpFac;
	Factory_lj ljFac;
	Factory_tgy tgyFac;

	DrinkBase* dhpFac_ptr = dhpFac.TeaMake();
	dhpFac_ptr->make();//Making a red gown

	DrinkBase* ljFac_ptr = ljFac.TeaMake();
	ljFac_ptr->make();//Making Longjing

	DrinkBase* tgyFac_ptr = tgyFac.TeaMake();
	tgyFac_ptr->make();//Making Tie Guan Yin

	delete dhpFac_ptr;
	delete ljFac_ptr;
	delete tgyFac_ptr;
	
	return 0;
}

Run result:

Corresponding models:

It can be seen that the biggest difference between the factory method mode and the simple factory mode is that the simple factory mode puts a class of products into one factory and the factory method mode has a corresponding factory production for each product. So there are many factory classes in the factory method mode, but there is a very big advantage: Makes up for the fatal damage of the simple factory model - following the open and close principle. If the factory method mode requires products to be added, then it is good to add specific product classes and specific factories that produce this specific product. The disadvantage is that there are too many classes and the degree of packaging is too low. Low coupling in low coupling and high cohesion is achieved, but high cohesion is not reflected.
Take a look at the evaluation of simple factory mode by Chinese Language C website
Advantage:
Users only need to know the name of a specific factory to get the products they want, not the process of creating them.
Enhanced flexibility, only one additional factory class is required for new product creation.
Typical decoupling framework. High-level modules only need to know the abstract classes of the product, not care about other implementation classes, and satisfy Dimitt's, Inverted Dependency, and Richter Replacement principles.
Disadvantages:
The number of classes can easily be too large and add complexity
Increased abstraction and difficulty in understanding systems
An abstract product can only produce one product, and this drawback can be solved by using the abstract factory model.
Scenarios:
The customer only knows the factory name where the product was created, not the specific product name. Such as TCL TV factory, Haixin TV factory, etc.
The task of creating objects is accomplished by one of several specific subfactories, while an abstract factory only provides the interface for creating products.
Customers don't care about the details of creating a product, they only care about the brand of the product

3. Abstract Factory Mode

1. Basic concepts and model structure

Definition of abstract factory schema: A schema structure that provides an access class with an interface to create a set of related or interdependent objects, and that obtains different levels of products of the same family without specifying a specific class of the desired product.
The abstract factory mode is an upgraded version of the factory method mode, which produces only one level of product, while the abstract factory mode can produce multiple levels of products.
Using the abstract factory pattern generally meets the following conditions:
There are multiple product families in the system, and each specific factory creates products of the same family but belonging to different hierarchies.
The system can only consume one of these products at a time, that is, products of the same family.
The structure of the pattern
The main roles of the abstract factory pattern are as follows.
**Abstract Products: ** Defines product specifications, describes the main features and functions of the product, and abstract factory mode has more than one abstract product.
**Specific Product:** Implements the interface defined by the abstract product role, created by the specific factory, which has a many-to-one relationship with the specific factory.
**Abstract Factory: ** Provides an interface for creating a product that includes multiple methods for creating a product, newProduct(), which can create multiple products of different levels.
**Specific factory:** Implements several abstract methods in an abstract factory to complete the creation of a specific product.

2. Code samples and models

Code:

class AbstractRGT //Abstract Product Class, Refrigerator
{
public:
	virtual ~AbstractRGT() {}
	virtual void make_rgt() = 0;
};

class HaierRGT :public AbstractRGT 
{
public:
	void make_rgt()
	{
		cout << "Make a Haier refrigerator!" << endl;
	}
};

class MeidiRGT :public AbstractRGT 
{
public:
	void make_rgt()
	{
		cout << "Make a beautiful refrigerator!" << endl;
	}
};

class GeliRGT :public AbstractRGT
{
public:
	void make_rgt()
	{
		cout << "Make a Gree refrigerator!" << endl;
	}
};



class AbstractAIRCDT //Abstract Product Class, Air Conditioning
{
public:
	virtual ~AbstractAIRCDT() {}
	virtual void make_aircdt() = 0;
};

class MeidiAIRCDT :public AbstractAIRCDT 
{
public:
	void make_aircdt()
	{
		cout << "Make a beautiful air conditioner!" << endl;
	}
};

class HaierAIRCDT :public AbstractAIRCDT
{
public:
	void make_aircdt()
	{
		cout << "Make a Haier air conditioner!" << endl;
	}
};

class GeliAIRCDT :public AbstractAIRCDT
{
public:
	void make_aircdt()
	{
		cout << "Make a GREEN AIR CONTROL!" << endl;
	}
};



class AbstractFactory //Abstract factory class, where brand is a commodity family
{
public:
	virtual ~AbstractFactory() {}
	virtual AbstractAIRCDT* Aircdt_make() = 0;
	virtual AbstractRGT* Rgt_make() = 0;
};

class HaierFactory:public AbstractFactory//Commodities of the Haier Nationality
{
public:
	AbstractAIRCDT* Aircdt_make()
	{
		return new HaierAIRCDT();
	}
	AbstractRGT* Rgt_make()
	{
		return new HaierRGT();
	}
};

class MeidiFactory :public AbstractFactory//Shangping of the Beautiful Nation
{
public:
	AbstractAIRCDT* Aircdt_make()
	{
		return new MeidiAIRCDT();
	}
	AbstractRGT* Rgt_make()
	{
		return new MeidiRGT();
	}
};

class GeliFactory :public AbstractFactory//Goods of the Gli Nationality
{
public:
	AbstractAIRCDT* Aircdt_make()
	{
		return new GeliAIRCDT();
	}
	AbstractRGT* Rgt_make()
	{
		return new GeliRGT();
	}
};

int main()
{
	MeidiFactory meidi_fac;
	AbstractAIRCDT* meidiair_ptr = meidi_fac.Aircdt_make();
	meidiair_ptr->make_aircdt();
	AbstractRGT* meidirgt_ptr = meidi_fac.Rgt_make();
	meidirgt_ptr->make_rgt();

	HaierFactory haier_fac;
	AbstractAIRCDT* haierair_ptr = haier_fac.Aircdt_make();
	haierair_ptr->make_aircdt();
	AbstractRGT* haierrgt_ptr = haier_fac.Rgt_make();
	haierrgt_ptr->make_rgt();

	GeliFactory geli_fac;
	AbstractAIRCDT* geliair_ptr = geli_fac.Aircdt_make();
	geliair_ptr->make_aircdt();
	AbstractRGT* gelirgt_ptr = geli_fac.Rgt_make();
	gelirgt_ptr->make_rgt();

	return 0;
}

Run result:

Model:

Advantage:
The multilevel products associated with a product family can be managed together within a class without having to introduce several new classes specifically for management.
When a product family is required, an abstract factory can ensure that clients always use only one product group for the same product.
The abstract factory enhances the extensibility of the program, and when a new family of products is added, there is no need to modify the original code to satisfy the open and close principle.

The disadvantage is that when a new product needs to be added to the product family, all factory classes need to be modified. It increases the abstraction and difficulty of understanding the system.
Structure and implementation of patterns
The abstract factory mode, like the factory method mode, is composed of four elements: Abstract factory, specific factory, abstract product and specific product. However, the number of methods and abstract products in the abstract factory is different. Now let's analyze its basic structure and implementation.
Scenarios applicable:
(1) When the object to be created is a series of related or interdependent product families, such as TV sets, washing machines, air conditioning in electrical equipment factories, etc.
(2) There are multiple product families in the system, but only one of them is used at a time. If someone only likes to wear certain brand of clothes and shoes.
(3) Class libraries for products are provided in the system, and all products have the same interfaces. Clients do not depend on the details and internal structure of product instances.
Extension of pattern:
The expansion of the abstract factory model has a certain "tilt" of the open-close principle:
When a new product family is added, only a new specific factory needs to be added, and the original code does not need to be modified to meet the open and close principle.
When a new product type needs to be added to the product family, all factory classes need to be modified to not meet the open and close principle.
On the other hand, when there is only one hierarchical product in the system, the abstract factory mode will degenerate to the factory method mode.

Topics: C++ Design Pattern