有谁知道是否有可能有一个像记录器这样的类而没有:
使用单例或全局(例如 std::cout)
将实例/指针/引用传递给每个需要它的方法
我以记录器类为例,但我的应用程序中有一些类可以从中受益(例如,撤消管理器)。
每个解决方案都有几个问题:
使用单例对测试来说是有问题的(以及许多原因,使用单例通常不是一个好主意)。全局也是一样。此外,没有什么能保证应用程序中只有一个实例,甚至不是必需的(例如,为什么没有 2 个记录器?)
将它传递给每个对象构造函数(依赖注入(inject)),会导致大量样板代码,并且可能容易出错,因为您必须多次复制/粘贴相同的代码。可以认真考虑在每个类的构造函数中都有一个指向 Logger 的指针吗??????
所以我想知道是否有第三种替代方案,在 C++ 中,我从未听说过? 对我来说,这听起来像是需要一些黑魔法,但我对我在堆栈溢出中学到的一些我在谷歌找不到的技术感到惊喜,所以我知道这里有一些真正的大师;)
令人惊讶的是,我发现很多关于如何设计单例或为什么不应该使用单例的讨论,但我找不到解决我的问题的帖子...
最佳答案
我想你可以用 Log4j 包做类似于 Java 中所做的事情(并且可能用它的 Log4c 版本完成):
有一个可以返回多个记录器实例的静态方法:
Logger someLogger = Logger.getLogger("logger.name");
getLogger()
方法没有返回单例对象。它返回命名的记录器(如有必要,创建它)。 Logger
只是一个接口(interface)(在 C++ 中它可能是一个完全抽象的类)——调用者不需要知道正在创建的 Logger
对象的实际类型。
你可以继续模仿 Log4j 并有一个 getLogger()
的重载,它也需要一个工厂对象:
Logger someLogger = Logger.getLogger("logger.name", factory);
该调用将使用 factory
来构建记录器实例,让您可以更好地控制正在创建的底层 Logger
对象,这可能有助于您的模拟。
因此,无需将任何内容传递给您自己代码的构造函数、方法等。您只需在需要时获取所需的名为 Logger
并登录到它。根据您编写的日志记录代码的线程安全性,您可以将 getLogger()
返回的内容作为类的静态成员,因此您只需调用 getLogger()
每堂课一次。
关于c++:没有全局变量或单例或将其传递给每个方法的记录器类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5877779/