c + + factory mode

Keywords: C++ Design Pattern Back-end

Before you get familiar with factory mode, you should first understand the six guidelines before writing c + + programs

  1. Opening and closing principle: do not modify existing codes, only add codes.
  2. Dependency Inversion Principle: use abstract classes instead of concrete classes to solve problems. (isolation change, package change)
  3. Richter substitution principle: Where any base class can appear, subclasses must appear.
  4. Interface isolation principle: use interface isolation logic to reduce coupling.
  5. Demeter's Law: there is no interaction between classes, so that the functions are independent of each other.
  6. Single responsibility principle: a class has only one reason to change

Factory mode is divided into three categories. The following will introduce simple factory and factory mode
Simple factory
There is only one abstract class, so its disadvantage is that all creation logic is concentrated in the factory class, and the problem of high cohesion has not been solved. When products need to be added, the factory class needs to be modified, which violates the first opening and closing principle of the six guidelines and has no good expansibility. But its existence is not accidental. Its advantage is that it hides the internal creation from the outside, which is conducive to the optimization of the whole structure.

Example: four operations
Four operations illustrate that there are four different operation modes. When you choose one, each is a different logic. However, the premise of the four operations is the need for a calculator. Therefore, the simple factory pattern will execute different logic according to the operators you enter. The code is as follows
#include
#include

class Cal//Calculator class
{
public:
	virtual void getResult(int a, int b) = 0;
};

class Add :public Cal
{
public:
	void getResult(int a, int b)
	{
		std::cout << a + b << std::endl;
	}
};
class Sub :public Cal
{
public:
	void getResult(int a, int b)
	{
		std::cout << a - b << std::endl;
	}
};
class Mul :public Cal
{
public:
	void getResult(int a, int b)
	{
		std::cout << a * b << std::endl;
	}
};
class Div :public Cal
{
public:
	void getResult(int a, int b)
	{
		std::cout << a / b << std::endl;
	}
};

class EasyFactory
{
public:
	Cal* createobj(char op)//Define the parent class pointer and access the child class function
	{
		switch (op)
		{
			case'+':
			{
				return new Add();
				break;
			}
			case'-':
			{
				return new Sub();
				break;
			}
			case'*':
			{
				return new Mul();
				break;
			}
			case'/':
			{
				return new Div();
				break;
			}
		}
	}
};



int main()
{
	int a = 8, b = 2;
	char op;
	std::cin >> op;
	Cal* cal = EasyFactory().createobj(op);//Get and return different objects through different operators
	cal->getResult(a,b);
	return 0;
}

Factory mode
Recall the four operations just now. If you want to add a remainder operation, how should you add it?
Obviously, we must first define a remainder class to inherit the Cal class. Secondly, you need to add a case node in EasyFactory, which obviously changes the EasyFactory class and violates the opening and closing principle. Therefore, we need to isolate the EasyFactory class, so the factory pattern is generated. The code is as follows

#include <iostream>
#include <string>

class Cal//Calculator class
{
public:
	virtual void getResult(int a, int b) = 0;
};

class Add :public Cal
{
public:
	void getResult(int a, int b)
	{
		std::cout << a + b << std::endl;
	}
};
class Sub :public Cal
{
public:
	void getResult(int a, int b)
	{
		std::cout << a - b << std::endl;
	}
};
class Mul :public Cal
{
public:
	void getResult(int a, int b)
	{
		std::cout << a * b << std::endl;
	}
};
class Div :public Cal
{
public:
	void getResult(int a, int b)
	{
		std::cout << a / b << std::endl;
	}
};

class AbsFactory
{
public:
	virtual Cal* createobj() = 0;
};

class AddFactory :public AbsFactory
{
public:
	Cal* createobj()
	{
		return new Add();
	}
};
class SubFactory :public AbsFactory
{
public:
	Cal* createobj()
	{
		return new Sub();
	}
};
class MulFactory :public AbsFactory
{
public:
	Cal* createobj()
	{
		return new Mul();
	}
};
class DivFactory :public AbsFactory
{
public:
	Cal* createobj()
	{
		return new Div();
	}
};

int main()
{
	int a = 8, b = 2;
	char op;
	Cal* cal;
	AbsFactory* factory = nullptr;
	std::cin >> op;
	switch (op)
	{
		case'+':
		{
			factory = new AddFactory();
			break;
		}
		case'-':
		{
			factory = new SubFactory();
			break;
		}
		case'*':
		{
			factory = new MulFactory();
			break;
		}
		case'/':
		{
			factory = new DivFactory();
			break;
		}
		default:
		{
			break;
		}
	}
	cal = factory->createobj();
	cal->getResult(a,b);

	return 0;
}

Posted by dessolator on Mon, 08 Nov 2021 08:15:28 -0800