大话设计模式——工厂模式

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值