简介


 简单工厂模式(Simple Factory Pattern)属于类的创建型模式(但是简单工厂模式不属于23种设计模式之一),又叫静态工厂方法模式(Static FactoryMethod Pattern), 是通过专门定义一个类来负责创建其他类的实例,这个类可以根据不同变量返回不同类的产品实例被创建的实例通常都具有共同的基类


大话设计模式 —— 第一章《简单工厂模式》
ProductA、ProductB 和 ProductC 继承自Product抽象类,Show方法是不同产品的自描述;Factory依赖于ProductA、ProductB和ProductC。 Factory根据不同的条件 创建不同的Product 对象。
  • 抽象(Product)产品:简单工厂模式所创建的所有对象的父类,注意:这里的父类可以是接口也可以是抽象类,它负责描述所有实例所共有的公共接口。
  • 具体产品(Concrete Product):简单工厂所创建的具体实例对象,这些具体的产品往往都拥有共同的父类。
  • 工厂角色(Creator):这是简单工厂模式的核心,由它负责创建所有的类的内部逻辑。当然工厂类必须能够被外界调用,创建所需要的产品对象。

 

对于工厂模式,具体上可以分为三类:

  • 简单工厂模式;
  • 工厂方法模式;
  • 抽象工厂模式。

工厂模式有一种非常形象的描述,建立对象的类就如一个工厂,而需要被建立的对象就是一个个产品;在工厂中加工产品,使用产品的人,不用在乎产品是如何生产出来的。从软件开发的角度来说,这样就有效的降低了模块之间的耦合。

 


 

 

简单工厂模式深入分析:

简单工厂模式解决的问题是:

  • 如何去实例化一个合适的对象。

简单工厂模式的核心思想就是:

  • 有一个专门的类来负责创建实例的过程。

具体来说,把产品看着是一系列的类的集合,这些类是由某个抽象类或者接口派生出来的一个对象树。而工厂类用来产生一个合适的对象来满足客户的要求。

如果简单工厂模式所涉及到的具体产品之间没有共同逻辑,那么我们就可以使用接口来扮演抽象产品的角色

如果具体产品之间有功能的逻辑,我们就必须把这些共同的东西提取出来,放在一个抽象类中,然后让具体产品继承抽象类。为实现更好复用的目的,共同的东西总是应该抽象出来的。

 


适用场合:

在程序中,需要创建对象很多,导致对象的new操作且很复杂时,需要使用简单工厂模式;

● 由于对象创建过程是我们不需要去关心的,而我们注重的是对象的实际操作,所以,我们需要分离对象的创建操作两部分,如此,方便后期的程序扩展和维护。

 


 

代码实现为:

#include<iostream>
using namespace std;

class Operation  //抽象运算类
{
public:
	
	double getA()
	{
		return m_numberA;
	}
	void setA(double value)
	{
		m_numberA = value;
	}


	double getB()
	{
		return m_numberB;
	}
	void setB(double value)
	{
		m_numberB = value;
	}

	virtual double getResult() = 0;
	
	virtual ~Operation() = default;
protected:
	Operation() {}
	double m_numberA = 0;
	double m_numberB = 0;
};

class OperationAdd : public Operation  //加法类,继承运算类
{
public:
	double getResult()override
	{
		double result = m_numberA + m_numberB;
		return result;
	}
};

class OperationSub : public Operation  //减法类,继承运算类
{
public:
	double getResult()override
	{
		double result = m_numberA - m_numberB;
		return result;
	}
};

class OperationMul : public Operation  //乘法类,继承运算类
{
public:
	
	double getResult()override
	{
		double result = m_numberA * m_numberB;
		return result;
	}
};

class OperationDiv : public Operation  //除法类,继承运算类
{
public:
	double getResult()override
	{
		double result = 0;
		if (m_numberB != 0)
		{
			 result = m_numberA / m_numberB;
		}
		else
		{
			return -1;
		}
		return result;
	}
};

class OperationFactory  //工厂类    
{
public:
	static Operation *createOperation(char type)
	{
		Operation *operation = nullptr;
		switch (type)
		{
		case '+':
			operation = new OperationAdd;
			break;
		case '-':
			operation = new OperationSub;
			break;
		case '*':
			operation = new OperationMul;
			break;
		case '/':
			operation = new OperationDiv;
			break;
		}
		return operation;
	}
};

int main()
{


	while (true)
	{
		cout << "\n请输入第一个数进行计算:";
		double strNumberA;
		cin >> strNumberA;

		cout << "\n请先输入四则运算符号,进行相应的运算(+、-、*、/):\n" << endl;
		char SignOfOperation = ' ';
		while (cin >> SignOfOperation)
		{
			if (SignOfOperation == '+' || SignOfOperation == '-' || SignOfOperation == '*' || SignOfOperation == '/')
			{
				break;
			}
			else
			{
				cout << "请输入正确运算符号,否则无法进行计算,请重新输入:";
				continue;
			}
		}

		cout << "请输入第二个数进行计算:";
		double strNumberB;
		cin >> strNumberB;

		{
			cout << "\n*************************************************************" << endl
				<< "********************   计算器基本功能展示.   **********************" << endl
				<< "*****************************************************************" << endl
				<< "********************   选择1——进行加法.   **********************" << endl
				<< "********************   选择2——进行减法.   **********************" << endl
				<< "********************   选择3——进行乘法.   **********************" << endl
				<< "********************   选择4——进行除法.   **********************" << endl
				<< "********************   选择5——清屏.   **********************" << endl
				<< "********************   选择0——退出程序!   **********************" << endl
				<< "*****************************************************************" << endl;
		}
	

		cout << "\n********************   请输入你想要使用的计算器的序号   ***************" << endl;
		cout << "请输入你的选择:";
		int userChoice(0);

		if (cin >> userChoice && userChoice == 0)
		{
			cout << "程序已退出,感谢您的使用!" << "\n" << endl;
			break;
		}
		Operation* oper = nullptr;
		
		switch (userChoice)
		{
		case 1:
			oper = OperationFactory::createOperation(SignOfOperation);
			oper->setA(strNumberA);
			oper->setB(strNumberB);
			cout << strNumberA << "+" << strNumberB << "=" << (oper->getResult()) << endl;
			break;

		case 2:
			oper = OperationFactory::createOperation(SignOfOperation);
			oper->setA(strNumberA);
			oper->setB(strNumberB);
			cout << strNumberA << "-" << strNumberB << "=" << (oper->getResult()) << endl;
			break;
		case 3:
			oper = OperationFactory::createOperation(SignOfOperation);
			oper->setA(strNumberA);
			oper->setB(strNumberB);
			cout << strNumberA << "*" << strNumberB << "=" << (oper->getResult()) << endl;
			break;

		case 4:
		{
			oper = OperationFactory::createOperation(SignOfOperation);
			oper->setA(strNumberA);
			oper->setB(strNumberB);
			if (double temp = oper->getResult())
			{
				cout << strNumberA << "/" << strNumberB << "=" << temp << endl;
			}
			else
			{
				cout << "错误,除数不能为0!" << endl;
			}
			break;
		}
		case 5:
			system("cls");
			cout << "屏幕已经清屏,可以重新输入!" << "\n" << endl;
			break;
		default:
			cout << "输入的序号不正确,请重新输入!" << "\n" << endl;
		}
		delete oper;
		oper = nullptr;
	}
	system("pause");
	return 0;
}

 

简单工厂模式的优缺点分析:

 

  • 优点: 工厂类是整个模式的关键所在。它包含必要的判断逻辑,能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。 用户在使用时可以直接根据工厂类去创建 所需的实例,而无需了解这些对象是如何创建以及如何组织的。有利于整个软件体系结构的优化。
  • 缺点:由于工厂类集中了所有实例的创建逻辑,这就直接导致一旦这个工厂出了问题,所有的客户端都会受到牵连;而且由于简单工厂模式的产品是基于一个共同的抽象类或者接口,这样一来,一但产品的种类增加的时候,即有不同的产品接口或者抽象类的时候,工厂类就需要判断何时创建何种种类的产品,这就和创建何种种类产品的产品相互混淆在了一起,违背了单一职责,导致系统丧失灵活性和可维护性。
  • 而且更重要的是: 简单工厂模式违背了“开放封闭原则”,就是违背了“系统对扩展开放,对修改关闭”的原则,因为当我们新增加一个产品的时候必须修改工厂类,相应的工厂类就需要重新编译一遍。

总结一下:

  • 简单工厂模式把产品的创建者和消费者分离,有利于软件系统结构的优化;但是由于一切逻辑都集中在一个工厂类中,导致了没有很高的内聚性,同时也违背了“开放封闭原则”。
  • 另外,简单工厂模式的方法一般都是静态的,而静态工厂方法是无法让子类继承的,因此,简单工厂模式无法形成基于基类的继承树结构。

 

 

相关文章:

  • 2021-10-01
  • 2019-01-09
  • 2018-04-18
  • 2021-11-30
  • 2020-02-05
  • 2017-11-27
猜你喜欢
  • 2019-07-27
  • 2019-05-26
  • 2021-05-21
  • 2019-01-25
  • 2021-12-04
  • 2021-09-21
  • 2021-09-21
  • 2021-10-01
相关资源
相似解决方案