Example comparison of simple factory and factory method patterns in C++ design pattern programming
- 2020-05-09 19:00:12
- OfStack
Example of a simple factory pattern
Title: the implementation of the calculator input 2 Numbers and operators, the results
Engineering structure:
(1) header files
COperationFactory.h (operator factory class)
(2) the source file
SimpleFactory.cpp (client application class, where the main function is)
(3) class
COperation. cpp (operator base class)
COperation.h
COperationAdd.h (addition operator subclass, inherited from COperation)
COperationDiv.h (subclass of division operator, inherited from COperation)
COperationMul.h (multiplication operator subclass, inherited from COperation)
COperationSub.h (subclass of subtraction operator, inherited from COperation)
============= == code implementation ============= =====
COperationFactory.h (operator factory class)
/************************************************************************/
/* Operator factory class */
/************************************************************************/
#ifndef _OPERATION_FACTORY_H_
#define _OPERATION_FACTORY_H_
#include "stdafx.h"
#include "COperation.h"
#include "COperationAdd.h"
#include "COperationSub.h"
#include "COperationMul.h"
#include "COperationDiv.h"
#include "COperationFactory.h"
class COperationFactory
{
public:
COperationFactory(){};
~COperationFactory(){};
// The corresponding operator class pointer is created according to the input parameters. Like a factory, create a user-specified operator class pointer
static COperation* NewOperation(const string& strOperate)
{
// Enter the legitimacy judgment to prevent the latter strOperate[0] Cross-border visits occurred
if (strOperate.size() != 1)
{
return NULL;
}
COperation* pOperation = NULL;
switch (strOperate[0])
{
case '+':
pOperation = new COperationAdd();
break;
case '-':
pOperation = new COperationSub();
break;
case '*':
pOperation = new COperationMul();
break;
case '/':
pOperation = new COperationDiv();
break;
default:
break;
}
return pOperation;
};
};
#endif _OPERATION_FACTORY_H_
COperation.cpp (operator base class)
#include "stdafx.h"
#include "COperation.h"
COperation::COperation()
: _dNumA(0)
, _dNumB(0)
{
}
COperation.h
/************************************************************************/
/* Operator base class */
/************************************************************************/
#ifndef _COPERATION_H_
#define _COPERATION_H_
class COperation
{
public:
COperation();
~COperation(){};
// Sets the number to be evaluated
void SetNumA(double dNumA)
{
_dNumA = dNumA;
};
// Gets the number to be evaluated
double GetNumA()
{
return _dNumA;
};
// Set operand
void SetNumB(double dNumB)
{
_dNumB = dNumB;
};
// Fetch operand
double GetNumB()
{
return _dNumB;
};
// Calculate the result and implement the result of the respective operation method in the subclass
virtual double Result()
{
double dResult = 0;
return dResult;
}
private:
double _dNumA;
double _dNumB;
};
#endif _COPERATION_H_
COperationAdd.h (addition operator subclass, inherited from COperation)
/************************************************************************/
/* The addition operator subclass, which is inherited from the operator base class */
/************************************************************************/
#ifndef _COPERATION_ADD_H_
#define _COPERATION_ADD_H_
#include "COperation.h"
class COperationAdd : public COperation
{
public:
COperationAdd(){};
~COperationAdd(){};
double Result()
{
return (GetNumA() + GetNumB());
};
};
#endif _COPERATION_ADD_H_
COperationDiv.h (subclass of division operator, inherited from COperation)
/************************************************************************/
/* Subclass of the division operator, which is inherited from the operator base class */
/************************************************************************/
#ifndef _COPERATION_DIV_H_
#define _COPERATION_DIV_H_
#include "COperation.h"
class COperationDiv : public COperation
{
public:
COperationDiv(){};
~COperationDiv(){};
double Result()
{
double dResult = 0;
if (0 != GetNumB())
{
dResult = (GetNumA() / GetNumB());
}
else
{
cout << "error: divisor is ";
}
return dResult;
};
};
#endif _COPERATION_DIV_H_
COperationMul.h (multiplication operator subclass, inherited from COperation)
/************************************************************************/
/* A subclass of the multiplication operator that is inherited from the operator base class */
/************************************************************************/
#ifndef _COPERATION_MUL_H_
#define _COPERATION_MUL_H_
#include "COperation.h"
class COperationMul : public COperation
{
public:
COperationMul(){};
~COperationMul(){};
double Result()
{
return (GetNumA() * GetNumB());
};
};
#endif _COPERATION_MUL_H_
COperationSub.h (subclass of subtractive operator, inherited from COperation)
/************************************************************************/
/* Subclasses of subtractive operators, which are inherited from the operator base class */
/************************************************************************/
#ifndef _COPERATION_SUB_H_
#define _COPERATION_SUB_H_
#include "COperation.h"
class COperationSub : public COperation
{
public:
COperationSub(){};
~COperationSub(){};
double Result()
{
return (GetNumA() - GetNumB());
};
};
#endif _COPERATION_SUB_H_
SimpleFactory.cpp (client application class, where the main function is)
// SimpleFactory.cpp : Define the entry point for the console application.
//
#include "stdafx.h"
#include "COperationFactory.h"
int _tmain(int argc, _TCHAR* argv[])
{
// Create an addition operation through an operator factory
COperation* OperAdd = COperationFactory::NewOperation("+");
if (NULL != OperAdd)
{
OperAdd->SetNumA(168); // Set the addend
OperAdd->SetNumB(105); // Set the addend
cout << "168 + 105 = " << (OperAdd->Result()) << endl;
}
// Creates a subtraction operation through an operator factory
COperation* OperSub = COperationFactory::NewOperation("-");
if (NULL != OperSub)
{
OperSub->SetNumA(168); // Set the minuend
OperSub->SetNumB(105); // Set the reduction
cout << "168 - 105 = " << (OperSub->Result()) << endl;
}
// Create the multiplication operation through the operator factory
COperation* OperMul = COperationFactory::NewOperation("*");
if (NULL != OperMul)
{
OperMul->SetNumA(168); // Set the multiplicand
OperMul->SetNumB(105); // Set the multiplier
cout << "168 * 105 = " << (OperMul->Result()) << endl;
}
// Creates a division operation through an operator factory
COperation* OperDiv = COperationFactory::NewOperation("/");
if (NULL != OperDiv)
{
OperDiv->SetNumA(168); // Set the dividend
OperDiv->SetNumB(105); // Set the divisor
cout << "168 / 105 = " << (OperDiv->Result()) << endl;
OperDiv->SetNumB(0); // Change the divisor
cout << (OperDiv->Result()) << endl;
}
// Prevents the console process from ending to facilitate viewing the results
int nEnd = 0;
cin >> nEnd;
return 0;
}
Abstract factory pattern instances
Engineering structure:
(1) abstract products
IFruit.h
(2) abstract factory class
IFruitGardener.h
(3) specific products
CApple.h
CGrape.h
CStrawberry.h
(4) specific factories
CAppleGardener.h
CGrapeGardener.h
CStrawberryGardener.h
(5) client
FactoryMethodApplication.cpp
(1) abstract products
IFruit.h
/************************************************************************/
/* Abstract fruits (abstract Product) */
/************************************************************************/
#ifndef _IFRUIT_H_
#define _IFRUIT_H_
#include <string>
#include <iostream>
using namespace std;
class IFruit
{
public:
virtual void grow() = 0;
virtual void harvest() = 0;
virtual void plant() = 0;
};
#endif _IFRUIT_H_
(2) abstract factory class
IFruitGardener.h
/************************************************************************/
/* Abstract fruit gardeners (abstract Factory) */
/************************************************************************/
#ifndef _IFRUIT_GARDENER_H_
#define _IFRUIT_GARDENER_H_
#include "IFruit.h"
class IFruitGardener
{
public:
virtual IFruit* Factory() = 0;
};
#endif _IFRUIT_GARDENER_H_
(3) specific products
CApple.h
#include "stdafx.h"
#include "COperation.h"
COperation::COperation()
: _dNumA(0)
, _dNumB(0)
{
}
0
CGrape.h
#include "stdafx.h"
#include "COperation.h"
COperation::COperation()
: _dNumA(0)
, _dNumB(0)
{
}
1
CStrawberry.h
#include "stdafx.h"
#include "COperation.h"
COperation::COperation()
: _dNumA(0)
, _dNumB(0)
{
}
2
(4) specific factories
CAppleGardener.h
/************************************************************************/
/* Specific apple gardener category (Concrete Factory) */
/************************************************************************/
#ifndef _APPLE_GARDENER_H_
#define _APPLE_GARDENER_H_
#include "IFruitGardener.h"
#include "CApple.h"
class CAppleGardener : public IFruitGardener
{
public:
CAppleGardener():m_pApple(NULL){};
IFruit* Factory()
{
if (NULL == m_pApple)
{
m_pApple = new CApple();
}
return m_pApple;
};
private:
CApple* m_pApple;
};
#endif _APPLE_GARDENER_H_
CGrapeGardener.h
#include "stdafx.h"
#include "COperation.h"
COperation::COperation()
: _dNumA(0)
, _dNumB(0)
{
}
4
CStrawberryGardener.h
#include "stdafx.h"
#include "COperation.h"
COperation::COperation()
: _dNumA(0)
, _dNumB(0)
{
}
5
(5) client
FactoryMethodApplication.cpp
#include "stdafx.h"
#include "COperation.h"
COperation::COperation()
: _dNumA(0)
, _dNumB(0)
{
}
6
conclusion
First of all, both the simple factory pattern and the factory method pattern extract the invariable places and encapsulate the easily changed ones. In order to achieve a large degree of reuse, and adapt to user changes, as well as the expansion of the project.
1. Simple factory model
1. Understand
Also known as the static factory pattern, it defines a class that is responsible for creating instances of other classes, which usually have the same parent class. The factory class dynamically determines which instances of the product class should be created based on the parameters passed in. It contains the necessary judgment logic to determine which concrete class of objects should be worn based on the given information. The simple factory model can be understood as a father leaving a sum of money for his son to go to school, buy a house or a car, and then letting the son choose which one to use.
2. The advantages
The factory class contains the necessary logic to determine when to create an instance of which class, and the client can avoid creating objects directly. In this way, the division of responsibilities can be realized, the coupling can be reduced, and the specific responsibilities and powers can be defined, which is conducive to the optimization of the whole system.
3. The shortcomings
When the product has a relatively complex multi-layer structure, its factory class is only 1, at this time, it will become its biggest disadvantage. Because the factory class is the core of the whole organization, it gathers the creation logic of all products. Once the factory cannot work normally, the whole system will be affected and the scalability will be poor. When there are new requirements, the factory logic will have to be modified, which will lead to the complexity of the factory logic and violate the open-close principle. At the same time, the static factory method is not conducive to the formation of a hierarchical structure based on inheritance.
2. Factory method mode
1. Understand
It is a fine-grained design pattern because the representation of the pattern is an abstract method. The factory method pattern defines an interface for creating objects and lets subclasses decide which class to instantiate. In other words, the interface is added between the factory and the product. The factory is no longer responsible for the implementation of the product. There is an excuse to return different class instances for different conditions, and then the concrete class instances will be implemented. The factory method is a derivative of the simple factory, which improves many of the disadvantages of the simple factory, follows the open-close principle, and achieves scalability, which can be used in more complex product results. The factory method can be understood as the same father left his son a sum of money, and then directly let the son to control, how to spend the father 1 law does not care.
2. The advantages
The factory method model overcomes many of the disadvantages of simple factories. It only completes the single task per specific factory, and follows the open-close principle. The code is concise and has good scalability.
3. The shortcomings
If a product class needs to be modified, the corresponding factory class also needs to be modified. Once there are more than one product class that needs to be modified, the problem of matching will appear, and it will become quite complicated to modify the factory class. So the factory method pattern, while good for scaling, is bad for maintenance.
With all of this in mind, we can see which pattern is most beneficial for programming in different situations. The simple factory pattern can be used when there are few objects to create and the customer only knows the parameters passed into the factory and does not care how to create the objects. The factory method pattern is used when a class delegates responsibility for creating an object to one of several help subclasses.