c++ 工厂模式

什么是工厂模式

工厂模式(Factory
Pattern)是设计模式中的一种,属于创建型模式。它的核心思想是为了解耦对象的创建过程与使用过程,让代码更加灵活,易于扩展和维护。工厂模式通过引入一个工厂类来负责对象的创建,而客户端代码只需要与这个工厂类交互,无须关心具体的对象创建细节。这样做有以下几个优点:

封装性:隐藏了对象创建的具体逻辑,客户端代码不需要知道对象是如何被创建出来的。
开放封闭原则:当需要添加新的产品时,只需要增加一个新的具体产品类和修改工厂类(或新增一个工厂子类),不需要修改现有代码,符合软件设计的开放封闭原则。
代码复用:相同的创建逻辑可以复用,减少了代码重复。
替换和选择的灵活性:客户端可以根据不同的条件选择创建不同产品类的实例。

使用工厂模式的原因

解耦:工厂模式将对象的创建与使用分离,使得代码的生产和消费部分解耦。这有助于遵循单一职责原则,即让一个类只负责一件事情,既创建对象又使用对象的职责被分开,提高了代码的可维护性和可读性。

提高灵活性和可扩展性:当需要添加新的产品类型时,只需要增加新的产品类和相应的工厂方法(或新的工厂类),而不需要修改现有的客户端代码。这使得系统易于扩展,符合开闭原则,即对扩展开放,对修改关闭。

隐藏实现细节:客户端代码不需要知道具体产品的创建细节,如构造函数参数、初始化过程等。这些细节被封装在工厂内部,降低了模块间的耦合度,使得代码更加整洁和易于理解。

促进代码复用:通用的工厂逻辑可以被复用,特别是当使用抽象工厂模式时,可以创建一系列相关的产品族,而无需为每个产品单独编写创建逻辑。

控制对象的创建过程:工厂模式允许在创建过程中执行额外的逻辑,比如记录日志、执行性能监控、管理资源或者处理异常情况,而不会把这些逻辑混入到业务代码中。

便于使用配置和策略变化:通过配置文件或策略模式,可以在运行时决定使用哪个工厂或创建哪种产品,增加了系统的灵活性。

使用工厂模式的案例

  • 日志记录系统:系统中可能需要支持多种日志记录方式,如文件日志、数据库日志、网络日志等。通过工厂模式,可以创建一个日志记录器工厂,根据配置动态创建不同类型的日志记录器对象,而不需要修改日志记录的调用代码。

  • 数据库访问:在需要支持多种数据库(如MySQL、SQL Server、Oracle)的系统中,可以使用工厂模式创建数据库连接和操作的实例。工厂类根据传入的数据库类型参数,返回对应的数据库操作对象,使得客户端代码无需关注具体数据库的差异。

  • GUI组件创建:在图形界面开发中,可能需要根据不同的平台(如Windows、MacOS、Linux)创建不同风格的UI组件。通过工厂模式,可以创建一个UI组件工厂,根据当前运行的平台来生成相应的UI组件实例。

  • 图片处理服务:一个图片处理服务可能支持多种处理算法(如缩放、旋转、滤镜等)。使用工厂模式,可以为每种处理算法创建一个工厂类,根据用户请求动态生成处理算法的实例。

  • 网络请求库:在网络通信库中,可能需要根据不同的协议(HTTP、HTTPS、WebSocket等)创建不同的请求处理器。工厂模式可以用来根据协议类型创建相应的请求处理器对象。

  • 游戏开发中的角色创建:在游戏开发中,根据不同的角色类型(战士、法师、弓箭手等),可以使用工厂模式创建不同的游戏角色实例,每个实例具有不同的属性和行为。

  • 文档解析器:在处理不同格式文档(如XML、JSON、YAML)的应用中,工厂模式可以用来根据文档类型创建对应的解析器对象,客户端代码只需调用工厂方法而不必知道具体的解析逻辑。

简单工厂模式实现步骤

1.提供一个抽象工厂类 :所有具体工厂类的父类

2.提供与产品对应的工厂类:负责实例化产品对象

3.提供一个抽象产品类: 所有产品的父类

4.提供一个或多个产品类:工厂方法模式所创建的具体实例对象

在这里插入图片描述

简单工厂实现代码

#include <iostream>
#include <string>
using namespace std;
//产品抽象父类
class Operation 
{	

public:
	double m_leftVlaue;
	double m_rightValue;
	virtual double GetResult() = 0;
};
//具体产品实现类
class AddOperation:public Operation
{
	double GetResult()
	{
		return m_leftVlaue + m_rightValue;
	}
};
class SubOperation :public Operation 
{
	double GetResult()
	{
		return m_leftVlaue - m_rightValue;
	}
};

class MulOperation :public Operation
{
	double GetResult()
	{
		return m_leftVlaue * m_rightValue;
	}
};

class DivOperation :public Operation
{
	double GetResult()
	{
		return m_leftVlaue / m_rightValue;
	}
};
//工厂类
class  OperatorFactory 
{
public:
	static  Operation* createOperation(char c) 
	{
		switch (c) 
		{
		case '+':
			return new AddOperation;
			break;
		case '-':
			return new SubOperation;
			break;
		case '*':
			return new MulOperation;
			break;
		case '/':
			return new DivOperation;
			break;
		}
	}
};
int main() 
{
	Operation* operation = OperatorFactory::createOperation('+');
	operation->m_leftVlaue = 1;
	operation->m_rightValue = 2;
	cout << operation->GetResult() << endl;
	return 0;
}

简单工厂优缺点

优点

  • 帮助封装

    实现组件封装,面向接口编程

  • 解耦合

    客户端和具体实现类的解耦合

缺点

  • 可能增加客户端的复杂度
  • 不方便扩展子工厂

工厂模式

工厂模式是一个广义的概念,它包含了几种子模式,比如简单工厂模式、工厂方法模式和抽象工厂模式。这些模式都属于创建型设计模式,旨在隐藏对象创建的具体过程,提供一个统一的接口来创建对象。下面是工厂模式和其子类模式简单工厂模式的主要区别:
工厂模式概述

目的:提供一个创建对象的接口,让子类决定实例化哪一个类。这样做的好处是,客户端代码不需要知道它所创建的对象的具体类,降低了模块间的耦合度,提高了代码的扩展性和灵活性。
分类:工厂模式主要有简单工厂、工厂方法和抽象工厂三种形态,每种形态适用于不同的复杂度和需求变化场景。

简单工厂模式

定义:简单工厂模式又称静态工厂方法模式,它有一个专门的工厂类,根据传入的参数来创建并返回一个具体的产品对象。这个工厂类包含了必要的逻辑来判断应该创建哪个产品的实例。
特点:
    优点在于实现简单,客户端不需要知道具体产品的创建细节。
    缺点是当添加新产品时,需要修改工厂类的代码,违反了开闭原则(对扩展开放,对修改关闭)。
    适用场景:产品种类相对较少,不会频繁变动的情况。

工厂方法模式

定义:工厂方法模式定义了一个用于创建对象的接口,但让子类决定实例化哪一个类。也就是说,工厂方法将对象的实例化推迟到了子类。
特点:
    相比简单工厂,工厂方法模式更加灵活,因为它支持多个工厂子类,每个工厂子类负责创建一类产品。
    当需要增加新产品时,只需要添加对应的产品类和工厂子类,不需要修改现有的代码,符合开闭原则。
    适用场景:产品种类多,经常需要扩展,或者产品等级结构复杂的场景。

在这里插入图片描述

工厂模式实现步骤

1.提供一个抽象工厂类 :所有具体工厂类的父类

2.提供与产品对应的工厂类:负责实例化产品对象

3.提供一个抽象产品类: 所有产品的父类

4.提供一个或多个产品类:工厂方法模式所创建的具体实例对象

代码示例

#include <iostream>
using namespace std;
//造火箭造飞机
//抽象产品类
class AbstractProduct
{
public:
	virtual ~AbstractProduct() {};
	virtual void makeProduct() = 0;
};

//抽象工厂
class  AbstractFactory
{
public:
	virtual ~AbstractFactory() {}
	virtual AbstractProduct* CreateProduct() = 0;
};

//具体产品类
//飞机
class PlaneProduct:public AbstractProduct
{
public:
	void makeProduct() 
	{
		cout << "飞机......" << endl;
	}
};
class PlaneFactory :public AbstractFactory 
{
	AbstractProduct* CreateProduct() 
	{
		return  new PlaneProduct;
	}
};
//火箭
class RocketProduct :public AbstractProduct 
{
public:
	void makeProduct() 
	{
		cout << "火箭......" << endl;
	}
};
class RocketFactory :public AbstractFactory
{
	AbstractProduct* CreateProduct() 
	{
		return new RocketProduct;
	}
};
void test(AbstractFactory* factory,AbstractProduct* product)
{
	factory->CreateProduct();
	product->makeProduct();
}

int main() 
{
	AbstractFactory* factory = new PlaneFactory;
	AbstractProduct* product = factory->CreateProduct();
	product->makeProduct();

	factory = new RocketFactory;
	product = factory->CreateProduct();
	product->makeProduct();
	return 0;
}

抽象工厂

什么是抽象工厂模式

抽象工厂模式是所有形态的工厂模式中最为抽象和最一般性的。抽象工厂模式可以向 客户端提供一个接口,使得客户端在不必指定产品的具体类型的情况下,能够创建多个产品族的产品对象。

为什么使用抽象工厂模式

抽象工厂方法是针对与一个产品族,使得易于交换产品系列,只需改变具体的工厂就可以使用不同的产品配置。当一个族中的产品对象被设计成一起工作且一个应用只是用同一族的对象,例如设计系统生成不同风格的UI界面,按钮,边框等UI元素在一起使用,并且只能同属于一种风格,这很容易使用抽象工厂实现。

抽象工厂模式实现步骤

1.提供一个抽象工厂类: 声明一组创建一族产品的工厂方法

2.提供一个具体工厂类: 实现了在抽象工厂创建产品的工厂方法

3.提供一个抽象产品类: 抽象产品中声明了产品具有的业务方法

4.提供一个具体产品类: 实现抽象产品接口中声明的业务方法
在这里插入图片描述

抽象工厂模式实现代码

#include <iostream>
using namespace std;
//抽象产品
class Product 
{
public:
	virtual void show() = 0;
};
//抽象产品族1
class KeyBoard :public Product {};

//具体产品
class LogiKeyBoard :public KeyBoard 
{
	void show() 
	{
		cout << "罗技键盘......" << endl;
	}
};
class RazerKeyBoard :public KeyBoard 
{
	void show()
	{
		cout << "雷蛇键盘......" << endl;
	}
};

//抽象产品族2
class Mouse :public Product {};
class LogiMouse :public Mouse 
{
	void show()
	{
		cout << "罗技鼠标......" << endl;
	}
};
class RazerMouse :public Mouse
{
	void show() 
	{
		cout << "雷蛇鼠标......" << endl;
	}
};
//抽象工厂
class Factory 
{
public :
	virtual  KeyBoard* CreateKeyBoard() = 0;
	virtual Mouse* CreateMouse() = 0;
};

//具体工厂
//罗技工厂
class LogiFactory :public Factory 
{
	KeyBoard* CreateKeyBoard() 
	{
		return new LogiKeyBoard;
	}
	Mouse* CreateMouse() 
	{
		return new LogiMouse;
	}
};
//雷蛇工厂
class RazerFactory :public Factory 
{
	KeyBoard* CreateKeyBoard() 
	{
		return  new RazerKeyBoard;
	}
	Mouse* CreateMouse() 
	{
		return new RazerMouse;
	}
};

int main() 
{

	Factory* factory = new LogiFactory;
	KeyBoard* keyBoard = factory->CreateKeyBoard();
	Mouse* mouse = factory->CreateMouse();
	keyBoard->show();
	mouse->show();
	delete factory;
	delete keyBoard;
	delete mouse;

	factory = new RazerFactory;
	keyBoard = factory->CreateKeyBoard();
	mouse = factory->CreateMouse();
	keyBoard->show();
	mouse->show();
	delete factory;
	delete keyBoard;
	delete mouse;
	factory = nullptr;
	keyBoard = nullptr;
	mouse = nullptr;
	return 0;
}

抽象工厂模式优缺点

优点

  • 抽象工厂封装了变化,封装了对象创建的具体细节
  • 增加新的产品族很方便,无须修改已有系统
  • 针对接口进行编程而不是针对具体进行编程

缺点:

  • 增加新的产品等级结构需对原系统做较大修改(违背开放封闭)
  • 15
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值