设计模式之工厂模式(C++)

Posted 翟天保Steven

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式之工厂模式(C++)相关的知识,希望对你有一定的参考价值。

作者:翟天保Steven
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处

一、工厂模式是什么?

       工厂模式是一种创建型的软件设计模式。定义一个用于创建对象的工厂接口,并让工厂子类决定实例化哪一个产品类,使产品类的实例化延迟到工厂子类中执行。说白了就是用来造东西的,一般是比较简单的东西,我们不需要知道它如何生产的,直接从工厂拿到产品即可。

       工厂模式的优点:

  1. 良好的封装性。将产品的实例化封装执行,避免被修改,这样的产品具备良好的一致性。
  2. 良好的扩展性。增加产品时,同步增加一个工厂子类,不会违反开闭原则。
  3. 标准的解耦合框架。使用者只需要知道自己要什么产品即可,不用去管产品具体的特性等等,降低了模块间的耦合。

      工厂模式的缺点:

  1. 代码量大。每加一个产品,都要加一个工厂子类,代码会显得臃肿。
  2. 不利于扩展复杂的产品结构。如果你要苹果、香蕉、梨,工厂模式的结构还可以,但如果你要山东的苹果、海南的香蕉、北京的苹果,就显得结构呆呆的。这可以用抽象工厂模式解决,对产品族和产品种类进行区分。

二、简单工厂模式

       在介绍工厂模式前,先介绍其前身-简单工厂模式,简单工厂模式是用一个简单的工厂类,直接对产品进行实例化,虽然大大减少了代码量,但是违反了设计中的开闭原则,因为每次添加产品,工厂类都要进行修改。

2.1 结构图

       客户端即Main主函数,调用简单工厂制造产品,并获取产品。具体要什么产品由客户端命令决定。

 2.2 代码示例

       场景描述:我联系了一个生产水果的工厂,从工厂拿了一个苹果、一个香蕉和一个梨,用来果腹,工厂给我一个报价我付钱即可。

//Prodect.h
/****************************************************/
#pragma once
#include <iostream>

using namespace std;

// 产品种类
enum PRODECT_TYPE

	APPLE,                     // 苹果
	BANANA,					   // 香蕉
	PEAR					   // 梨
;

// 抽象产品类
class Prodect

public:
	// 构造函数
	Prodect(int price) :m_price(price) ;
	// 析构函数
	virtual ~Prodect() ;
	// 获取价格
	int getPrice() 
		return m_price;
	
protected:
	// 产品价格
	int m_price;
;

// 具体产品类-苹果
class AppleProdect : public Prodect

public:
	// 构造函数
	AppleProdect(int price) :Prodect(price) 
		cout << "获得了一个苹果。" << endl;
	;
	// 析构函数
	virtual ~AppleProdect() 
		cout << "吃掉了一个苹果。" << endl;
	;
;

// 具体产品类-香蕉
class BananaProdect : public Prodect

public:
	// 构造函数
	BananaProdect(int price) :Prodect(price) 
		cout << "获得了一个香蕉。" << endl;
	;
	// 析构函数
	virtual ~BananaProdect() 
		cout << "吃掉了一个香蕉。" << endl;
	;
;

// 具体产品类-梨
class PearProdect : public Prodect

public:
	// 构造函数
	PearProdect(int price) :Prodect(price) 
		cout << "获得了一个梨。" << endl;
	;
	// 析构函数
	virtual ~PearProdect() 
		cout << "吃掉了一个梨。" << endl;
	;
;

//Factory.h
/****************************************************/
#pragma once
#include <iostream>
#include "Prodect.h"

using namespace std;

// 简单工厂
class SimpleFactory

public:
	// 获取产品
	Prodect* getProdect(PRODECT_TYPE type) 
		Prodect* prodect = nullptr;
		switch (type)
		
		case APPLE:
			prodect = new AppleProdect(5);
			break;
		case BANANA:
			prodect = new BananaProdect(2);
			break;
		case PEAR:
			prodect = new PearProdect(3);
			break;
		default:
			cout << "无该产品。" << endl;
			break;
		
		return prodect;
	
;

//main.cpp
/****************************************************/
#include <iostream>
#include "Factory.h"
#include "Prodect.h"

using namespace std;

int main()

	SimpleFactory* factory = new SimpleFactory();
	cout << "开始生产。" << endl;
	Prodect *A = factory->getProdect(APPLE);
	Prodect *B = factory->getProdect(BANANA);
	Prodect *C = factory->getProdect(PEAR);
	int applePrice = A->getPrice();
	int bananaPrice = B->getPrice();
	int pearPrice = C->getPrice();
	int sum = A->getPrice() + B->getPrice() + C->getPrice();
	cout << "苹果价格:" << applePrice << "元。" << endl;
	cout << "香蕉价格:" << bananaPrice << "元。" << endl;
	cout << "梨子价格:" << pearPrice << "元。" << endl;
	cout << "累计消费:" << sum << "元。" << endl;
	delete A;
	delete B;
	delete C;
    delete factory;
	cout << "享用完毕。" << endl;
	return 0;

       程序结果如下。

        在上述示例中,我们可以看到,如果我想给工厂再添加一个产品,那么除了添加一个产品子类外,还要跑到简单工厂的类中进行switch的扩展,这样不利于代码的封装,破坏了开闭原则。而工厂模式的设计能弥补该不足。

三、工厂模式

3.1 结构图

       客户端即Main主函数,通过工厂子类来制造对应的产品,并获取产品。具体要什么产品由工厂子类决定。

 3.2 代码示例

       场景描述:我联系了一个生产水果的工厂,从工厂拿了一个苹果、一个香蕉和一个梨,用来果腹,工厂给我一个报价我付钱即可。

//Prodect.h
/****************************************************/
#pragma once
#include <iostream>

using namespace std;

// 抽象产品类
class Prodect

public:
	// 构造函数
	Prodect(int price) :m_price(price) ;
	// 析构函数
	virtual ~Prodect() ;
	// 获取价格
	int getPrice() 
		return m_price;
	
protected:
	// 产品价格
	int m_price;
;

// 具体产品类-苹果
class AppleProdect : public Prodect

public:
	// 构造函数
	AppleProdect(int price) :Prodect(price) 
		cout << "获得了一个苹果。" << endl;
	;
	// 析构函数
	virtual ~AppleProdect() 
		cout << "吃掉了一个苹果。" << endl;
	;
;

// 具体产品类-香蕉
class BananaProdect : public Prodect

public:
	// 构造函数
	BananaProdect(int price) :Prodect(price) 
		cout << "获得了一个香蕉。" << endl;
	;
	// 析构函数
	virtual ~BananaProdect() 
		cout << "吃掉了一个香蕉。" << endl;
	;
;

// 具体产品类-梨
class PearProdect : public Prodect

public:
	// 构造函数
	PearProdect(int price) :Prodect(price) 
		cout << "获得了一个梨。" << endl;
	;
	// 析构函数
	virtual ~PearProdect() 
		cout << "吃掉了一个梨。" << endl;
	;
;

//Factory.h
/****************************************************/
#pragma once
#include <iostream>
#include "Prodect.h"

using namespace std;

// 抽象工厂类
class Factory

public:
	// 获取产品
	virtual Prodect* getProdect() = 0;
;

// 具体工厂类-苹果
class AppleFactory : public Factory

public:
	// 获取产品
	virtual Prodect* getProdect() 
		Prodect* prodect = new AppleProdect(5);
		return prodect;
	
;

// 具体工厂类-香蕉
class BananaFactory : public Factory

public:
	// 获取产品
	virtual Prodect* getProdect() 
		Prodect* prodect = new BananaProdect(2);
		return prodect;
	
;

// 具体工厂类-梨
class PearFactory : public Factory

public:
	// 获取产品
	virtual Prodect* getProdect() 
		Prodect* prodect = new PearProdect(3);
		return prodect;
	
;

//main.cpp
/****************************************************/
#include <iostream>
#include "Factory.h"
#include "Prodect.h"

using namespace std;

int main()

	Factory* factoryA = new AppleFactory();
	Factory* factoryB = new BananaFactory();
	Factory* factoryC = new PearFactory();
	cout << "开始生产。" << endl;
	Prodect *A = factoryA->getProdect();
	Prodect *B = factoryB->getProdect();
	Prodect *C = factoryC->getProdect();
	int applePrice = A->getPrice();
	int bananaPrice = B->getPrice();
	int pearPrice = C->getPrice();
	int sum = A->getPrice() + B->getPrice() + C->getPrice();
	cout << "苹果价格:" << applePrice << "元。" << endl;
	cout << "香蕉价格:" << bananaPrice << "元。" << endl;
	cout << "梨子价格:" << pearPrice << "元。" << endl;
	cout << "累计消费:" << sum << "元。" << endl;
	delete A;
	delete B;
	delete C;
    delete factoryA;
    delete factoryB;
    delete factoryC;
	cout << "享用完毕。" << endl;
	return 0;

       程序结果如下。

        这样设计的好处就是如果多一个产品,那就只需要在产品类和工厂类中各扩展一个子类即可,不影响原有的程序。

四、总结

       我尽可能用较通俗的话语和直观的代码例程,来表述我对工厂模式的理解,或许有考虑不周到的地方,如果你有不同看法欢迎评论区交流!希望我举的例子能帮助你更好地理解工厂模式。

       如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!

以上是关于设计模式之工厂模式(C++)的主要内容,如果未能解决你的问题,请参考以下文章

设计模式之工厂模式C++实现

C++之工厂(factory)模式

C++设计模式之-工厂模式的总结

设计模式之抽象工厂模式(C++)

设计模式之抽象工厂模式(C++)

设计模式之工厂模式(C++)