C++ 设计模式之工厂方法模式

C++ 设计模式之工厂方法模式

简介

1、工厂方法模式是一种创建型设计模式,它提供了一种在不指定具体类的情况下创建对象的方法。工厂方法模式定义了一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。

2、工厂方法模式 (Factory Method)应用场景包括但不限于:
2.1、不知道用户需要创建的具体对象 :当你只知道需要创建的对象应该符合某个接口或基类,而不知道具体实现时,可以应用工厂方法模式。
2.2、需要对创建过程进行解耦 :当需要把对象的创建与使用的过程分离,以便系统更容易扩展,对创建过程进行更细粒度的控制时,工厂方法模式很有用。
2.3、希望用户扩展部分子系统时 :当设计一个库或框架,你希望用户能扩展其某些部分(例如添加新的产品),但又不希望他们修改现有的代码时,工厂方法模式能提供很好的解决方案。
2.4、类的实例化逻辑比较复杂 :如果某个对象的创建依赖于多个动态参数或配置,那么将这个复杂的逻辑从使用环境中抽离出来,放在工厂中,可以使代码更清晰、更易于维护。
2.5、提供一个库或工具时 :当你提供的是一个要被其他系统所集成的库或工具时,可以使用工厂方法让库用户能够在不改变库代码的情况下引入自定义行为。

3、工厂方法模式的构成
定义一个用于创建对象的接口,让子类决定实例化哪一个类。

3.1、抽象产品接口

class ILogger
{
public:
	virtual ~ILogger() {};
	virtual void Log(const std::string& strMessage) = 0;
};

3.2、具体产品

class FileLogger : public ILogger
{
public:
	void Log(const std::string& strMessage);
};

3.3、创建者工厂

class LoggerFactory
{
public:
	virtual ~LoggerFactory() {};
	virtual ILogger* CreateLogger() = 0;
};

3.4、具体工厂

class FileLoggerFactory : public LoggerFactory
{
	ILogger* CreateLogger();
};

4、工厂方法模式的优点:
4.1、解耦 :工厂方法模式可以将产品的实例化过程从客户端代码中解耦出来,降低系统的耦合度。
4.2、符合开闭原则 :系统更容易扩展,可以在不修改现有客户端代码的情况下引入新的产品类型,只需添加新的具体产品和对应的工厂类。
4.3、减少客户端代码的修改 :由于工厂类负责创建产品实例,客户端不需要修改代码就可以接受新的产品。
4.4、单一职责原则 :每个具体工厂类只负责创建单一产品,符合单一职责原则。
4.5、封装性良好 :客户端无需知道它所需要的具体产品类的类名,只需要知道相应的工厂即可,降低了实现细节的暴露。

5、工厂方法模式的缺点:
5.1、产生许多类 :每增加一个产品就需要新增具体产品类和对应的具体工厂类,这会导致类的数量成倍增加,系统变得复杂。
5.2、增加了代码的抽象性和理解难度 :工厂方法模式引入了抽象层次,用户需要了解工厂方法模式的概念以及它的运作方式,增加了学习成本。
5.3、可能在一定程度上影响性能 :对象的创建通常会涉及动态内存分配等资源消耗的操作,在某些性能敏感的应用场景中,可能会对性能造成影响。
5.4、系统结构复杂化 :如果有许多级别的继承,那么工厂方法模式可能会导致设计非常复杂,特别是在大型应用中,很难保持工厂的组织和管理。
5.5、重构现有代码困难 :将现有项目中的实例化逻辑改为使用工厂方法模式会牵涉广泛的重构,特别是当系统中创建对象的代码已经与许多类交织在一起时。

简单示例

1、定义

class ILogger
{
public:
	virtual ~ILogger() {};
	virtual void Log(const std::string& strMessage) = 0;
};

// 具体产品
// 1、文件类
class FileLogger : public ILogger
{
public:
	void Log(const std::string& strMessage);
};

// 2、控制台类
class ConsoleLogger : public ILogger
{
public:
	void Log(const std::string& strMessage);
};

// 3、网络类
class NetworkLogger : public ILogger
{
public:
	void Log(const std::string& strMessage);
};

// 创建者工厂
class LoggerFactory
{
public:
	virtual ~LoggerFactory() {};
	virtual ILogger* CreateLogger() = 0;
};

// 具体工厂
// 1、文件类
class FileLoggerFactory : public LoggerFactory
{
	ILogger* CreateLogger();
};

// 2、控制台类
class ConsoleLoggerFactory : public LoggerFactory
{
	ILogger* CreateLogger();
};

// 3、网络类
class NetworkLoggerFactory : public LoggerFactory
{
	ILogger* CreateLogger();
};

2、实现

void FileLogger::Log(const std::string& strMessage)
{
	std::cout << "FileLogger: " << strMessage << std::endl;
}

void ConsoleLogger::Log(const std::string& strMessage)
{
	std::cout << "ConsoleLogger: " << strMessage << std::endl;
}

void NetworkLogger::Log(const std::string& strMessage)
{
	std::cout << "NetworkLogger: " << strMessage << std::endl;
}

ILogger* FileLoggerFactory::CreateLogger()
{
	return new FileLogger();
}

ILogger* ConsoleLoggerFactory::CreateLogger()
{
	return new ConsoleLogger();
}

ILogger* NetworkLoggerFactory::CreateLogger()
{
	return new NetworkLogger();
}

3、调用

LoggerFactory* logfactory = nullptr;
ILogger* iLog = nullptr;
logfactory = new FileLoggerFactory();
iLog = logfactory->CreateLogger();
iLog->Log("写入文件");
logfactory = new ConsoleLoggerFactory();
iLog = logfactory->CreateLogger();
iLog->Log("写入控制台");
logfactory = new NetworkLoggerFactory();
iLog = logfactory->CreateLogger();
iLog->Log("写入网络");

delete logfactory;
delete iLog;
  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值