在閱讀了一篇關於基於策略的設計的文章並希望自己嘗試一些東西之後,我花了一些時間重新設計一次我曾經做過的記錄器類到基於策略的方法。使用記錄器的基於策略的方法
一些代碼:
template <class Filter, class Formatter, class Outputter>
class LoggerImpl : public LoggerBase {
public:
LoggerImpl(const Filter& filter = Filter(), const Formatter& formatter = Formatter(), const Outputter& outputter = Outputter());
~LoggerImpl();
void log(int channel, int loglevel, const char* msg, va_list list) const;
private:
const Filter mFilter;
const Formatter mFormatter;
const Outputter mOutputter;
};
template <class Filter, class Formatter, class Outputter>
LoggerImpl<Filter, Formatter, Outputter>::LoggerImpl(const Filter& filter, const Formatter& formatter, const Outputter& outputter) :
mFilter(filter), mFormatter(formatter), mOutputter(outputter) {
debuglib::logdispatch::LoggerMgr.addLogger(this);
}
typedef LoggerImpl<NoFilter, SimpleFormatter, ConsoleOutputter> ConsoleLogger;
typedef LoggerImpl<ChannelFilter, SimpleFormatter, VSOutputter> SimpleChannelVSLogger;
typedef LoggerImpl<NoFilter, SimpleFormatter, FileOutputter> FileLogger;
ConsoleLogger c;
SimpleChannelVSLogger a(const ChannelFilter(1));
FileLogger f(NoFilter(), SimpleFormatter(), FileOutputter("log.txt"));
// macro for sending log message to all current created loggers
LOG(1, WARN, "Test %d", 1423);
根據記錄我需要通過像SimpleChannelVsLogger內logchannel或FileOututter日誌文件的文件名的附加信息。
我將參數傳遞給LoggerImpl的構造函數作爲const引用,然後將它們複製到存儲在記錄器類中的對象中。 需要複製它們,因爲生命週期擴展不是通過將臨時創建的對象綁定到const引用時發生的函數參數傳遞的(此處更多:Does a const reference prolong the life of a temporary?)。
因此,第一件事情是:如果我不想使用指針,因爲我在使用模板時對運行時分配不感興趣,我想除了像上面那樣複製臨時創建的對象之外,沒有其他解決方案嗎?
複製東西中的實際問題現在與FileOutputter: 當然不能複製當然,所以如何複製FileOutputter對象包含流? 我想出了以下解決方案來克服這個問題:
struct FileOutputter {
// c_tor
FileOutputter() {}
// c_tor
explicit FileOutputter(const char* fname) {
mStream = std::make_shared<std::fstream>(fname, std::fstream::out);
}
// The copy c_tor will be invoked while creating any logger with FileOutputter
// FileLogger f(NoFilter(), SimpleFormatter(), FileOutputter("log.txt"));
// as all incoming paramters from the constructors stack frame are copied into the current instance of the logger
// as copying a file-stream is not permitted and not good under any means
// a shared pointer is used in the copy c_tor
// to keep the original stream until no reference is referring to it anymore
FileOutputter(const FileOutputter& other) {
mStream = other.mStream;
}
~FileOutputter() {
}
void out(const char* msg) const {
*mStream << msg;
}
std::shared_ptr<std::fstream> mStream;
};
不知怎的,我有感覺,這似乎有點複雜,「簡單記錄器類」,然而,這可能只是一個「問題」與策略在這種情況下基於設計的方法。
有什麼想法,歡迎
注意:你不應該重複的默認參數(「'=過濾器()'」等)的函數定義 –
謝謝,我糾正了。 – Chris