1. 简单工厂模式(Simple Factory Pattern)
简单工厂模式包含三个角色:
- 抽象产品类:一般为具体产品继承的父类 或者 实现的接口
- 具体产品类:继承 或 实现 抽象产品类角色,在工厂类 中 创建此类的 实例(对象)。
- 工厂类:本模式的核心,含有一定的逻辑判断,根据逻辑不同返回不同的具体工厂产品(利用了多态)。
简单工厂模式适用于业务较简单的情况,一般用于小项目或者具体产品很少扩展的情况。
(扩展产品需要修改工厂类,违反开闭原则
)
#include <iostream>
using namespace std;
class Calculator {
public:
virtual float getResult(float num1, float num2) = 0;
};
class AddCalculator :public Calculator { //加法
public:
float getResult(float num1, float num2) {
return num1 + num2;
}
};
class SubCalculator :public Calculator { //减法
public:
float getResult(float num1, float num2) {
return num1 - num2;
}
};
class MulCalculator :public Calculator { //乘法
public:
float getResult(float num1, float num2) {
return num1 * num2;
}
};
class DivCalculator :public Calculator { //除法
public:
float getResult(float num1, float num2) {
if (num2 > -0.000001 && num2 < 0.000001) {
throw "error of dividing zero.";
}
else {
return num1 / num2;
}
}
};
//***********************************//
//创建运算工厂 ——简单工厂模式 如果新增加运算方法,需要更改原代码,不符合开闭原则
class CalculatorSimpleFactory {
public:
// 静态方法
static Calculator* createCalculator(char cType) {
switch (cType)
{
case '+':
return new AddCalculator;
break;
case '-':
return new SubCalculator;
break;
case '*':
return new MulCalculator;
break;
case '/':
return new DivCalculator;
break;
default:
return NULL;
break;
}
}
};
void test01(float num1, float num2, char cType) {
Calculator* cal = CalculatorSimpleFactory::createCalculator(cType); //静态方法的调用
cout << cal->getResult(num1, num2) << endl;
delete cal;
}
//***********************************//
int main() {
try {
float numberA;
cout << "请输入数字A:";
cin >> numberA;
char cType;
cout << "请选择运算符号(+、-、*、/):";
cin >> cType;
float numberB;
cout << "请输入数字B:";
cin >> numberB;
test01(numberA, numberB, cType);
}
catch (const char* error) { //注意这里是 char 类型
cout << error << endl;
}
return 0;
}
策略模式
//***********************************//
//策略模式
class CalculatorContext { //维护一个 对 Calculator 对象的引用
public:
CalculatorContext(Calculator* cal) {
mCal = cal;
}
float getResult(float num1, float num2) {
return mCal->getResult(num1, num2);
}
private:
Calculator* mCal;
};
void test01(float num1, float num2, char cType) {
CalculatorContext* calContext;
switch (cType)
{
case '+':
calContext = new CalculatorContext(new AddCalculator);
cout << calContext->getResult(num1, num2) << endl;
break;
case '-':
calContext = new CalculatorContext(new SubCalculator);
cout << calContext->getResult(num1, num2) << endl;
break;
case '*':
calContext = new CalculatorContext(new MulCalculator);
cout << calContext->getResult(num1, num2) << endl;
break;
case '/':
calContext = new CalculatorContext(new DivCalculator);
cout << calContext->getResult(num1, num2) << endl;
break;
default:
break;
}
}
//***********************************//
简单工厂与策略模式结合
//***********************************//
//简单工厂 + 策略模式
class CalculatorContextPro {
public:
CalculatorContextPro(char cType) {
switch (cType)
{
case '+':
mCal = new AddCalculator;
break;
case '-':
mCal = new SubCalculator;
break;
case '*':
mCal = new MulCalculator;
break;
case '/':
mCal = new DivCalculator;
break;
default:
mCal = NULL;
break;
}
}
float getResult(float num1, float num2) {
return mCal->getResult(num1, num2);
}
private:
Calculator* mCal;
};
void test01(float num1, float num2, char cType) {
CalculatorContextPro* calContextPro = new CalculatorContextPro(cType);
cout << calContextPro->getResult(num1, num2) << endl;
}
//***********************************//
对比简单工厂 与 策略模式和简单工厂结合的用法
//简单工厂
void test01(float num1, float num2, char cType) {
Calculator* cal = CalculatorSimpleFactory::createCalculator(cType); //静态方法的调用
cout << cal->getResult(num1, num2) << endl;
delete cal;
}
//简单工厂和策略模式结合
void test01(float num1, float num2, char cType) {
CalculatorContextPro* calContextPro = new CalculatorContextPro(cType);
cout << calContextPro->getResult(num1, num2) << endl;
}
简单工厂模式需要让客户端 认识 两个类 抽象类(Calculator) 和工厂类(CalculatorSimpleFactory)
简单工厂和策略模式结合 只需客户端 认识一个类 CalculatorContextPro 即可。
2. 工厂方法模式(Factory Method Pattern)
//***********************************//
//工厂方法模式
class CalculatorFactory {
public:
virtual Calculator* createCalculator() = 0;
};
class AddCalculatorFactory :public CalculatorFactory {
public:
virtual Calculator* createCalculator() {
return new AddCalculator;
}
};
class SubCalculatorFactory :public CalculatorFactory {
public:
virtual Calculator* createCalculator() {
return new SubCalculator;
}
};
class MulCalculatorFactory :public CalculatorFactory {
public:
virtual Calculator* createCalculator() {
return new MulCalculator;
}
};
class DivCalculatorFactory :public CalculatorFactory {
public:
virtual Calculator* createCalculator() {
return new DivCalculator;
}
};
void test01(float num1, float num2, char cType) {
switch (cType)
{
case '+':
{
CalculatorFactory* calFactory = new AddCalculatorFactory;
Calculator* addCal = calFactory->createCalculator();
cout << addCal->getResult(num1, num2) << endl;
break;
}
case '-':
{
CalculatorFactory* subCal = new SubCalculatorFactory;
cout << subCal->createCalculator()->getResult(num1, num2) << endl;
break;
}
case '*':
{
CalculatorFactory* mulCal = new MulCalculatorFactory;
cout << mulCal->createCalculator()->getResult(num1, num2) << endl;
break;
}
case '/':
{
CalculatorFactory* divCal = new DivCalculatorFactory;
cout << divCal->createCalculator()->getResult(num1, num2) << endl;
break;
}
default:
break;
}
}
//***********************************//
//main 函数同上
简单工厂 与 工厂方法 比较:
简单工厂模式的最大优点在于工厂类中包含了必要的逻辑判断,根据客户的选择条件动态实例化相关的类,对客户端来说,去除了与具体产品的依赖。
工厂方法模式实现时,客户端需要决定实例化哪一个工厂来实现 Calculator 类,选择判断问题还是存在的,也就是说,工厂方法把简单工厂的内部逻辑判断转移到了 客户端 代码中实现,如增加功能,本来改工厂类的,现在需要修改客户端。
3. 抽象工厂模式(Abstract Factory Pattern)
理解产品族和产品等级
产品族:一个品牌下面的所有产品;例如华为下面的加法器,减法器,乘法器,除法器 称为华为的产品族;
产品等级:多个品牌下面的同种产品;例如华为和小米下面的加法器 称为一个产品等级;
#include <iostream>
using namespace std;
class AddCalculator {
public:
virtual float getResult(float num1, float num2) = 0;
};
class AddCalculatorA :public AddCalculator {
public:
float getResult(float num1, float num2) {
cout << "AddCalculatorA:";
return num1 + num2;
}
};
class AddCalculatorB :public AddCalculator {
public:
float getResult(float num1, float num2) {
cout << "AddCalculatorB:";
return num1 + num2;
}
};
class SubCalculator {
public:
virtual float getResult(float num1, float num2) = 0;
};
class SubCalculatorA :public SubCalculator {
public:
float getResult(float num1, float num2) {
cout << "SubCalculatorA:";
return num1 - num2;
}
};
class SubCalculatorB :public SubCalculator {
public:
float getResult(float num1, float num2) {
cout << "SubCalculatorB:";
return num1 - num2;
}
};
//***********************************//
//抽象工厂模式
class CalculatorAbstractFactory {
public:
virtual AddCalculator* createAddCalculator() = 0;
virtual SubCalculator* createSubCalculator() = 0;
};
class CalculatorAFactory :public CalculatorAbstractFactory {
public:
virtual AddCalculator* createAddCalculator() {
return new AddCalculatorA;
}
virtual SubCalculator* createSubCalculator() {
return new SubCalculatorA;
}
};
class CalculatorBFactory :public CalculatorAbstractFactory {
public:
virtual AddCalculator* createAddCalculator() {
return new AddCalculatorB;
}
virtual SubCalculator* createSubCalculator() {
return new SubCalculatorB;
}
};
void test01(float num1, float num2, char cType) {
switch (cType)
{
case 'A':
{
CalculatorAbstractFactory* calA = new CalculatorAFactory;
AddCalculator* addcal = calA->createAddCalculator();
SubCalculator* subcal = calA->createSubCalculator();
cout << addcal->getResult(num1, num2) << endl;
cout << subcal->getResult(num1, num2) << endl;
break;
}
case 'B':
{
CalculatorAbstractFactory* calB = new CalculatorBFactory;
cout << calB->createAddCalculator()->getResult(num1, num2) << endl;
cout << calB->createSubCalculator()->getResult(num1, num2) << endl;
break;
}
default:
break;
}
}
//***********************************//
int main() {
try {
float numberA;
cout << "请输入数字A:";
cin >> numberA;
char cType;
cout << "请选择计算器(A 或 B):";
cin >> cType;
float numberB;
cout << "请输入数字B:";
cin >> numberB;
test01(numberA, numberB, cType);
}
catch (const char* error) { //注意这里是 char 类型
cout << error << endl;
}
return 0;
}