C++23种设计模式之一简单工厂模式(一)
作用以及解决的问题
主要用于创建对象。新添加类时,不会影响以前的系统代码。核心思想是用一个工厂来
根据输入的条件产生不同的类,然后根据不同类的 virtual 函数得到不同的结果。
GOOD:适用于不同情况创建不同的类时
BUG:客户端必须要知道基类和工厂类,耦合性差
认识
我们把简单工厂方法归类到工厂方法中。工厂方法的目的是用来解决具有同一接口(基类)派生类对象的生成问题。
尽管可以通过类的构造函数生成对象,但是,如果派生类的数量很大——即使几十个不同的派生类——对于程序设计而言也是困难的。
这里有两个困难:其一是可读性,在一个程序里使用一个switch-case block判断具体的生成类型,程序几乎不能读,也增加了编码的难度;
其二是扩展性,如果增加了新的派生类,就需要修改switch-case block。
解决上面问题的方法是把对象实体和生成分开:把“生成”定义成一个类。
对于简单工厂方法,把用于生产每个对象的函数定义为一个类的函数;对于工厂方法,
把“生成”每个对象的方法定义为一个类:派生自一个工厂接口类。每个“生成”函数都返回派生类的接口指针。
从此可以看出,简单工厂方法其实没有增加程序的可读性和扩展性。对于工厂方法,可以在实际使用前把所有的生成类构造到一个序列里,
然后把所有对象编号,每个编号是其生成类在序列的位置。这样就避免了使用switch-case block。
类图如下:![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/edd44dbcfc5761a956dad20587d8303a.png)
代码如下:
main.cpp
#include<iostream>
#include"CFactory.h"
#include"COperation.h"
using namespace std;
void Calc(char c ,double A,double B)
{
COperation* oper = CFactory::CreateOperation(c);
cout << oper->GetResult(A, B) << endl;
if (oper != NULL)
{
delete oper;
oper = NULL;
}
}
int main()
{
double A, B;
cin >> A >> B;
Calc('-', A, B);
Calc('+', A, B);
Calc('*', A, B);
Calc('/', A, B);
getchar();
}
/COperation.h/
#pragma once
class COperation
{
public:
COperation();
~COperation();
virtual double GetResult(double A,double B) ;
private:
double m_A;
double m_B;
};
/COperation.cpp/
#include "COperation.h"
COperation::COperation():m_A(0.0),m_B(0.0)
{
}
COperation::~COperation()
{
}
double COperation::GetResult(double A,double B)
{
return 0.0;
}
CAdd.h
#pragma once
#include "COperation.h"
class CAdd :
public COperation
{
public:
CAdd();
~CAdd();
virtual double GetResult(double A, double B);
};
CAdd.cpp
#include "CAdd.h"
CAdd::CAdd()
{
}
CAdd::~CAdd()
{
}
double CAdd::GetResult(double A, double B)
{
return A+B;
}
CSub.h
#pragma once
#include "COperation.h"
class CSub :
public COperation
{
public:
CSub();
~CSub();
virtual double GetResult(double A, double B);
};
CSub.cpp
#include "CSub.h"
CSub::CSub()
{
}
CSub::~CSub()
{
}
double CSub::GetResult(double A, double B)
{
return A-B;
}
CDivision.h
#pragma once
#include "COperation.h"
class CDivision :
public COperation
{
public:
CDivision();
~CDivision();
virtual double GetResult(double A, double B);
};
CDivision.cpp
#include "CDivision.h"
CDivision::CDivision()
{
}
CDivision::~CDivision()
{
}
double CDivision::GetResult(double A, double B)
{
return A/B;
}
CMult.h
#pragma once
#include "COperation.h"
class CMult :
public COperation
{
public:
CMult();
~CMult();
virtual double GetResult(double A, double B);
};
#include "CMult.h"
CMult::CMult()
{
}
CMult::~CMult()
{
}
double CMult::GetResult(double A, double B)
{
return A*B;
}
CFactory.h
#pragma once
#include"COperation.h"
#include"CAdd.h"
#include"CDivision.h"
#include"CMult.h"
#include"CSub.h"
class CFactory
{
public:
static COperation *CreateOperation(char c);
};
#include "CFactory.h"
COperation * CFactory::CreateOperation(char c)
{
COperation * Operation=nullptr;
switch (c)
{
case '+':
Operation = new CAdd();
break;
case '-':
Operation = new CSub();
break;
case '*':
Operation = new CMult();
break;
case '/':
Operation = new CDivision();
break;
}
return Operation;
}
```![在这里插入图片描述](https://img-blog.csdnimg.cn/20200611180758548.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjI1Mjc1Nw==,size_16,color_FFFFFF,t_70)