工厂方法模式
简单工厂模式虽然简单,但存在一个很严重的问题,当系统中需要引入新产品时,由于静态工厂方法通过所传入参数的不同来创建不同的产品,这必定要修改工厂类的源代码,将违背“开闭原则”,如何实现增加新产品而不影响已有代码?工厂方法模式应运而生,本文将介绍第二种工厂模式——工厂方法模式
- 日志记录器的设计
软件公司欲开发一个系统运行日志记录器,该记录器可以通过多种途径保存系统的运行日志,如通过文件记录或数据库记录,用户可以通过修改配置文件灵活地更换日志记录方式,在设计各类日志记录器时,软件公司的开发人员发现需要对日志记录器进行一些初始化工作,初始化参数的设置过程较为复杂,而且某些参数的设置有严格的先后次序,否则可能会发生记录失败;如何封装记录器的初始化过程并保证多种记录器切换的灵活性时软件公司开发人员面临的一个难题
该日志记录器有两个设计要点:
- 需要封装日志记录器的初始化过程,这些初始化工作较为复杂,例如需要初始化其他的类,还有可能需要读取配置文件,导致代码较长,如果将它们都卸载构造函数中,会导致构造函数庞大,不利于代码的修改和维护
- 用户可能需要更换日志记录方式,在客户端代码中需要提供一种灵活的方式来选择日志记录器,尽量在不修改源代码的基础上更换或者增加日志记录方式
工厂模式实例
这里使用了上一文章中的代码
C++ 智能指针: 链接.
//日志记录器接口:抽象产品
struct Logger
{
virtual void writeLog() = 0;
Logger()
{
cout << "日志记录器接口" << endl;
}
virtual ~Logger() //会先析构子类再析构基类
{
cout << "~Logger:" << endl;
}
};
//数据库日志记录器:具体产品
class DatabaseLogger :public Logger
{
public:
DatabaseLogger()
{
cout << "DatabaseLogger::" << endl;
}
~DatabaseLogger()
{
cout << "~DatabaseLogger::" << endl;
}
void writeLog()
{
cout << "数据库日志记录" << endl;
}
};
//文件日志记录器:具体产品
class FileLogger :public Logger
{
public:
FileLogger()
{
cout << "FileLogger::" << endl;
}
~FileLogger()
{
cout << "~FileLogger" << endl;
}
void writeLog()
{
cout << "文件日志记录" << endl;
}
};
//日志记录器工厂接口:抽象工厂
struct LoggerFactory
{
virtual my_unique_ptr<Logger> createLogger() = 0;
LoggerFactory()
{
cout << "LoggerFactory" << endl;
}
~LoggerFactory()
{
cout << "~LoggerFactory" << endl;
}
};
//数据库日志记录器工厂类:具体工厂
class DatabaseLoggerFactory :public LoggerFactory
{
public:
DatabaseLoggerFactory()
{
cout << "DatabaseLoggerFactory" << endl;
}
~DatabaseLoggerFactory()
{
cout << "~DatabaseLoggerFactory" << endl;
}
my_unique_ptr<Logger> createLogger()
{
//连接数据库,代码胜利
//创建数据库日志记录器对象
//Logger* logger = new DatabaseLogger();
//初始化数据库日志记录器
return my_unique_ptr<Logger>(new DatabaseLogger());//数据库日志记录器创建
}
};
//文件日志记录器工厂类:具体工厂
class FileLoggerFactory :public LoggerFactory
{
public:
FileLoggerFactory()
{
cout << "FileLoggerFactory" << endl;
}
~FileLoggerFactory()
{
cout << "~FileLoggerFactory" << endl;
}
my_unique_ptr<Logger> createLogger()
{
return my_unique_ptr<Logger>(new FileLogger());
}
};
int main()
{
my_unique_ptr<LoggerFactory> factory(new FileLoggerFactory());//文件日志记录器工厂
my_unique_ptr<Logger> logger = factory->createLogger();
logger->writeLog();
factory.reset(new DatabaseLoggerFactory());
logger = factory->createLogger();
logger->writeLog();
return 0;
}
最终对象的析构由智能指针进行操作,智能指针自动进行堆区空间的管理
而相对于C++为什么没有垃圾回收机制:
因为在程序的编写中,使用到了堆区的资源,但是由于应用场景与管理方式不同,C++可以根据业务需求去完成内存池的管理