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

设计模式的一条重要原则是:在系统中引入新功能时,千万别去修改老代码,只去添加新代码即可!

==========================================================================

一、工厂模式概述:工厂工厂,顾名思义就是负责加工生产的方法,工厂模式属于“创建型设计模式”,他提供了一种创建对象的方式,不会对客户端暴露创建对象的逻辑,并且使用抽象工厂提供的公共接口来完成对象的创建,一句话概况就是工厂模式封装了不同对象的创建过程。

二、应用场景:
如果我们只有一个类classA,那需要用到他的时候直接new classA()即可,这最简单的。但是如果存在多个类classA,classB,classC,而且这些类长得比较相似,但在使用的时候需要根据不同的情况来创建不同的对象。此时就需要用到工厂模式了,实现客户端与目标类之间的解耦,客户端根本就不需要知道有哪些类,也不需要知道如何去实例化,它只需要提出条件,然后工厂就基于客户端提出的条件来决定实例化哪一个类。

三、场景模拟:利用工厂模式实现“加减乘除四则运算”。

工厂模式UML类图:

在这里插入图片描述
**废话少说,直接挒上实现代码

步骤1:定义抽象运算类Operation

class Operation
{
public:
	Operation() {}
	virtual ~Operation() {}
	virtual double GetResult() = 0;

	void setA(double a) {
		this->mNumberA = a;
	}

	void setB(double b) {
		this->mNumberB = b;
	}

protected:
	double mNumberA;
	double mNumberB;
};

步骤2:从抽象运算类中派生出具体运算类

// 加法运算类
class OperationAdd :public Operation
{
public:
	OperationAdd() {}
	~OperationAdd() {}

	virtual double GetResult()
	{
		return (mNumberA + mNumberB);
	}
};

// 减法运算类
class OperationSub :public Operation
{
public:
	OperationSub() {}
	~OperationSub() {}

	virtual double GetResult()
	{
		return (mNumberA - mNumberB);
	}
};

// 乘法运算类
class OperationMul :public Operation
{
public:
	OperationMul() {}
	~OperationMul() {}

	virtual double GetResult()
	{
		return (mNumberA * mNumberB);
	}
};

// 除法运算类
class OperationDiv :public Operation
{
public:
	OperationDiv() {}
	~OperationDiv() {}

	virtual double GetResult()
	{
		return (mNumberA / mNumberB);
	}
};

步骤3:定义抽象工厂类

class AbstractFactory
{
public:
	AbstractFactory() {}
	virtual ~AbstractFactory() {}

	virtual Operation* CreateOperation() = 0; // 声明一个专门用来创建对象的公共接口,具体工厂类继承并重写
};

步骤4:定义具体的工厂类

// 加法工厂(只负责生产加法对象)
class FactoryAdd :public AbstractFactory
{
public:
	FactoryAdd() {}
	~FactoryAdd() {}

	// 重写虚函数CreateOperation(),在其内部创建加法类对象并返回
	virtual Operation* CreateOperation()
	{
		return (new OperationAdd());
	}
};


// 减法工厂(只负责生产减法对象)
class FactorySub :public AbstractFactory
{
public:
	FactorySub() {}
	~FactorySub() {}

	virtual Operation* CreateOperation()
	{
		return (new OperationSub());
	}
};


// 乘法工厂(只负责生产乘法对象)
class FactoryMul :public AbstractFactory
{
public:
	FactoryMul() {}
	~FactoryMul() {}

	virtual Operation* CreateOperation()
	{
		return (new OperationMul());
	}
};


// 除法工厂(只负责生产除法对象)
class FactoryDiv :public AbstractFactory
{
public:
	FactoryDiv() {}
	~FactoryDiv() {}

	virtual Operation* CreateOperation()
	{
		return (new OperationDiv());
	}
};

客户端代码:

#include <QtCore/QCoreApplication>
#include <iostream>
#include "Factory.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

	char sign = '/';
	double result = 0;
	double A = 2.5, B = 0.5;

	// 把逻辑判断部分转移到客户端中去
	// 根据不同的条件,在各条case分支语句中 new 出不同的工厂对象,从而间接实例化不同的运算类
	AbstractFactory* operFactory = nullptr;
	Operation* oper = nullptr;

	switch (sign)
	{
		case '+':
			operFactory = new FactoryAdd();
			oper = operFactory->CreateOperation();
			oper->setA(A);
			oper->setB(B);
			result = oper->GetResult();
			break;

		case '-':
			operFactory = new FactorySub();
			oper = operFactory->CreateOperation();
			oper->setA(A);
			oper->setB(B);
			result = oper->GetResult();
			break;

		case '*':
			operFactory = new FactoryMul();
			oper = operFactory->CreateOperation();
			oper->setA(A);
			oper->setB(B);
			result = oper->GetResult();
			break;

		case '/':
			operFactory = new FactoryDiv();
			oper = operFactory->CreateOperation();
			oper->setA(A);
			oper->setB(B);
			result = oper->GetResult();
			break;
	}

	std::cout << A << sign << B << "=" << result;

	delete operFactory;
	delete oper;

    return a.exec();
}

在客户端中主要根据运算符sign的不同来动态选择具体的运算方法,当选择了除法运算时,结果如下:
在这里插入图片描述

四、总结

1、工厂模式的优点:
(1)扩展性好,如果想要增加一个产品,只需要扩展工厂类即可。
(2)封装性好,在客户端内想要创建一个对象时,并不需要知道该对象的创建细节,至需要知道其对应的工厂名即可。
(3)耦合性低,将具体产品的实现与客户端分离,使用者只需要关心产品的接口。

2、简单工厂模式VS工厂模式:
相同点:两种方法在处理产品类部分的思路是一致的,都是声明一个抽象产品类,然后从抽象产品类派生出各个具体的产品类,主要根据C++虚函数和多态的原理来动态地选择实例化哪个产品类。
不同点:两种方法在处理工厂类部分的思路不同。简单工厂模式直接就只有一个工厂类,在实例化产品类的时候,是把大量逻辑判断(switch、if)都放在了唯一的工厂类中,然后根据客户端设置的条件来动态选择实例化具体的产品类。然而工厂模式在此基础上做了升级,首先定义了一个抽象工厂,从抽象工厂中派生出具体工厂类,这样做的意义在于把原来简单工厂中的逻辑判断转移到了客户端中去。
当后期需要引入新的产品时,简单工厂方法需要修改工厂类中的逻辑判断和增加产品类,既做了修改也做了扩展;而工厂方法只需要增加新的具体工厂类和具体产品类即可,仅仅是做了扩展。后者符合“开闭原则”。

3、个人的顶级理解:
各种工厂模式,无论是简单工厂还是普通工厂还是抽象工厂,说白了,其实都在解决对象如何更加合理地进行创建的问题(new运算)。利用抽象类在顶层设计好统一的接口,把实例化过程延迟到子类中去实现,并做集中管理,这样就把实例化的过程从业务逻辑中解耦出去了。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
工厂模式是一种常见的创建型设计模式,用于创建对象,而不是通过直接调用构造函数来创建它们。工厂模式定义了一个接口,用于创建相关对象,但是让子类决定要实例化的类。在C++中,工厂模式可以通过以下步骤实现: 1. 创建一个抽象基类,该类定义了一个纯虚拟函数,该函数将返回一个指向基类的指针。这个基类就是我们的工厂接口。 ```c++ class Product { public: virtual ~Product() {} virtual void operation() = 0; }; ``` 2. 创建具体的产品类,它们继承自抽象基类,并实现了其纯虚拟函数。这些类就是我们的具体产品。 ```c++ class ConcreteProductA : public Product { public: void operation() override { /* 具体产品 A 的操作 */ } }; class ConcreteProductB : public Product { public: void operation() override { /* 具体产品 B 的操作 */ } }; ``` 3. 创建一个工厂类,该类实现了工厂接口,并根据需要创建具体的产品。这个工厂类就是我们的具体工厂。 ```c++ class Factory { public: virtual ~Factory() {} virtual std::unique_ptr<Product> createProduct() = 0; }; class ConcreteFactoryA : public Factory { public: std::unique_ptr<Product> createProduct() override { return std::make_unique<ConcreteProductA>(); } }; class ConcreteFactoryB : public Factory { public: std::unique_ptr<Product> createProduct() override { return std::make_unique<ConcreteProductB>(); } }; ``` 4. 在客户端代码中使用具体工厂创建具体产品。 ```c++ int main() { std::unique_ptr<Factory> factory = std::make_unique<ConcreteFactoryA>(); std::unique_ptr<Product> product = factory->createProduct(); product->operation(); return 0; } ``` 这就是工厂模式的基本实现方式。通过这种方式,我们可以将对象的创建过程与客户端代码分离,从而更好地实现模块化和可扩展性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值