建造者模式
建造者模式就是为了方便对象的构造,当零部件的构建和组装过于复杂时,就需要建造者模式来帮帮忙
这里我们的日志器很适合,但是也没有特别复杂,所以可以对整个设计模式进行简化,不需要指挥者,直接使用建造者进行组装
因为指挥者主要是为了各个零件构造的顺序而存在的,但是我们这里不需要规定顺序
设计
- 抽象日志器建造者类
- 设置日志器类型
- 将不同类型的日志器类型放在同一个日志器建造者类去完成
- 派生出具体的建造者
- 局部日志器建造者
- 全局日志器建造者(单例管理)
实现
// 使用建造者模式建造日志器,无需用户构造
enum class LoggerType
{
LOGGER_SYNC,
LOGGER_ASYNC
};
class LoggerBuilder
{
public:
LoggerBuilder()
: _logger_type(LoggerType::LOGGER_SYNC), _limit_level(LogLevel::value::DEBUG)
{
}
void buildLoggerType(LoggerType type)
{
_logger_type = type;
}
void buildLoggerName(const std::string &name)
{
_logger_name = name;
}
void buildLoggerLevel(LogLevel::value level)
{
_limit_level = level;
}
void buildFormatter(const std::string &pattern = "[%d{%y-%m-%d|%H:%M:%S}][%t][%c][%f:%l][%p]%T%m%n")
{
_formatter = std::make_shared<Formatter>(pattern);
}
template <typename SinkType, typename... Args>
void buildSink(Args &&...args)
{
LogSink::ptr psink = SinkFactory::create<SinkType>(std::forward<Args>(args)...);
_sinks.push_back(psink);
}
virtual Logger::ptr build() = 0;
protected:
LoggerType _logger_type;
std::string _logger_name;
LogLevel::value _limit_level;
Formatter::ptr _formatter;
std::vector<LogSink::ptr> _sinks;
};
// 局部日志器建造者
class LocalLoggerBuild : public LoggerBuilder
{
public:
Logger::ptr build() override
{
assert(!_logger_name.empty());
if (_sinks.empty())
{
buildSink<StdoutSink>();
}
if (_logger_type == LoggerType::LOGGER_ASYNC)
{
}
return std::make_shared<SyncLogger>(_logger_name, _limit_level, _formatter, _sinks);
}
};
// TODO 全局日志器建造者
测试
// 测试建造者模式
std::unique_ptr<Xulog::LoggerBuilder> builder(new Xulog::LocalLoggerBuild());
builder->buildLoggerLevel(Xulog::LogLevel::value::WARN);
builder->buildLoggerName("synclog");
builder->buildFormatter();
builder->buildLoggerType(Xulog::LoggerType::LOGGER_SYNC);
builder->buildSink<Xulog::StdoutSink>();
builder->buildSink<Xulog::FileSink>("./log/test.log");
builder->buildSink<Xulog::RollSinkBySize>("./log/roll-", 1024 * 1024);
builder->buildSink<RollSinkByTime>("./log/roll-", TimeGap::GAP_SECOND);
Xulog::Logger::ptr logger = builder->build();
std::string str = "测试同步日志器-";
logger->debug(__FILE__, __LINE__, "%s", str.c_str());
logger->error(__FILE__, __LINE__, "%s", str.c_str());
logger->fatal(__FILE__, __LINE__, "%s", str.c_str());
logger->info(__FILE__, __LINE__, "%s", str.c_str());
logger->warn(__FILE__, __LINE__, "%s", str.c_str());
size_t size = 0;
int cnt = 1;
while (size < 1024 * 1024 * 10) // 10 个
{
logger->fatal(__FILE__, __LINE__, "%s-%d", str.c_str(), cnt++);
size += 20;
}