工厂方法模式

理论

工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到起子类。

简单工厂 VS 工厂方法

相同点:它们都是集中封装了对象的创建,使得要更换对象时,不需要做大的改动就可以实现,降低了客户程序与产品对象的耦合。

简单工厂模式

  优点:在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖。

  缺点:如果需要加一个新的功能,需要在工厂类的方法里添加Case的分支条件,违背了开放-封闭原则。

工厂方法模式

  优点:是简单工厂模式的进一步抽象和推广,克服了简单工厂违背开放-封闭原则的缺点,又保持了封装对象创建过程的优点

  缺点:每增加一个产品,需要加一个产品工厂的类,增加了额外的开发量。

工厂方法模式实现时,客户端需要决定实例化哪一个工厂来实现运算类,选择判断的问题还是存在。也就是说,工厂方法把简单工厂的内部逻辑判断移到了客户端代码来进行。

实例1

用任意一种面向对象语言实现一个计算器控制台程序

UML类图

简单工厂模式

 工厂方法模式

 实现代码

#include <iostream>
#include <string>
using namespace std;

//抽象运算类
class Operation{
public:
	void GetNumber(int num1, int num2)
	{
		number_A = num1;
		number_B = num2;
	}

	virtual int GetResult() = 0;

protected:
	int number_A = 0;
	int number_B = 0;
};

//具体运算类
class OperationAdd :public Operation{
public:
	int GetResult()
	{
		return number_A + number_B;
	}
};

class OperationSub :public Operation{
public:
	int GetResult()
	{
		return number_A - number_B;
	}
};

class OperationMul :public Operation{
public:
	int GetResult()
	{
		return number_A * number_B;
	}
};

class OperationDiv :public Operation{
public:
	int GetResult()
	{
		if (number_B == 0)
		{
			cout << "除数不能为0" << endl;
			exit(0);
		}
		return number_A / number_B;
	}
};

//简单工厂类
class OperationFactory
{
public:
	static Operation* cerateOperate(char operate)
	{
		switch (operate)
		{
		case('+'):
			return new OperationAdd;
		case('-'):
			return new OperationSub;
		case('*'):
			return new OperationMul;
		case('/'):
			return new OperationDiv;
		default:
			break;
		}
	}
};

//抽象运算工厂类-->开闭原则: 对扩展开发,对修改关闭!!
class AbstractFactory {
public:
	virtual Operation* cerateOperate() = 0;
};

//加法类工厂
class AddFactory : public AbstractFactory {
public:
	Operation* cerateOperate()
	{
		return new OperationAdd();
	}
};

//减法类工厂
class SubFactory : public AbstractFactory {
public:
	Operation* cerateOperate()
	{
		return new OperationSub();
	}
};

//乘法类工厂
class MulFactory : public AbstractFactory {
public:
	Operation* cerateOperate()
	{
		return new OperationMul();
	}
};

//除法类工厂
class DivFactory : public AbstractFactory {
public:
	Operation* cerateOperate()
	{
		return new OperationDiv();
	}
};

//客户端
void test01()
{
	int num1 = 5;
	int num2 = 2;
	int result = 0;
	OperationFactory factory;
	Operation* operate = factory.cerateOperate('-');
	operate->GetNumber(num1, num2);
	result = operate->GetResult();
	cout << "num1 - num2 = " << result << endl;

	delete operate;
}

void test02()
{
	int num1 = 1;
	int num2 = 2;
	int result = 0;

	AbstractFactory* factory = new AddFactory();
	Operation* operate = factory->cerateOperate();
	operate->GetNumber(num1, num2);
	result = operate->GetResult();
	cout << "num1 + num2 = " << result << endl;

	delete operate;
	delete factory;
}

int main()
{
	test01();
	test02();

	system("pause");
	return 0;
}

实例2

学生/志愿者 以雷锋的名义做好事

实现代码

#include <iostream>
using namespace std;

//“雷锋”类
class Leifeng {
public:
	void Sweep()
	{
		cout << "扫地" << endl;
	}

	void Wash()
	{
		cout << "洗衣" << endl;
	}

	void BuyRice()
	{
		cout << "买米" << endl;
	}
};

//“学雷锋的大学生”类
class Undergraduate :public Leifeng {};

//“学雷锋的志愿者”类
class Volunteer :public Leifeng {};

//简单工厂类
class SimpleFactory {
public:
	static Leifeng* CreateLeifeng(int people)
	{
		Leifeng* result = NULL;
		switch (people)
		{
		case(1):
			result = new Undergraduate();
			break;
		case(2):
			result = new Volunteer();
			break;
		}
		return result;
	}
};

/*工厂方法模式*/

//雷锋工厂
class IFactory {
public:
	virtual Leifeng* CreatLeifeng() = 0;
};

//学雷锋的大学生工厂
class UndergraduateFactory : public IFactory{
public:
	Leifeng* CreatLeifeng()
	{
		return new Undergraduate();
	}
};

//社区志愿者工厂
class VolunteerFactory :public IFactory {
public:
	Leifeng* CreateLeifeng()
	{
		return new Volunteer();
	}
};

void test01()
{
	//简单工厂模式
	Leifeng* studentA = SimpleFactory::CreateLeifeng(1); //三句重复的代码
	studentA->BuyRice();
	Leifeng* studentB = SimpleFactory::CreateLeifeng(1);
	studentB->Sweep();
	Leifeng* studentC = SimpleFactory::CreateLeifeng(1);
	studentC->Wash();
}

void test02()
{
	//工厂方法模式
	IFactory* factory = new UndergraduateFactory(); //如果要换成社区志愿者类只需修改此处
	Leifeng* studentA = factory->CreatLeifeng();
	Leifeng* studentB = factory->CreatLeifeng();
	Leifeng* studentC = factory->CreatLeifeng();

	studentA->BuyRice();
	studentB->Sweep();
	studentC->Wash();

	delete factory;
	delete studentA;
	delete studentB;
	delete studentC;
}

int main()
{
	test01();
	cout << "---------------------" << endl;
	test02();

	system("pause");
	return 0;
}

  

posted @ 2022-09-06 19:13  KYZH  阅读(39)  评论(0)    收藏  举报