为什么要创建一个Logger对象,而不是在整个应用程序中使用静态日志记录方法?


14

以一个简单的Ruby on Rails应用程序为例。它Logger在应用程序加载过程中创建一个对象:

# in environment.rb
config.logger = Logger.new(<STDOUT | file | whatever>)

# and in our application we use this object
logger.warn "This process is taking too long to process. Optimization needed."

我的问题是,为什么我们不使用类方法(或静态方法)进行日志记录?会不会Logger.warnLogger.new.warn?或至少Logger.warn看似直观Logger.new.warn

即使Logger.new是单例对象,它提供什么好处?

Answers:


17

这是一个使用Java的示例。自从我使用log4j已经有一段时间了,但是根据我的记忆,整个log4j日志记录工具都会从XML文件初始化。XML文件本身可以包含多个配置不同的记录器(您在其中写入内容,写入的级别等)。因此,在这种情况下,您将具有记录器对象,而不是记录器静态方法,以便指定要调用的记录器。就是

Logger logger = Logger.get("Network");

会记录与网络连接,丢包等有关的信息,或者

Logger logger = Logger.get("Application");

它将记录与您的业务逻辑/应用程序相关的事情。至少使用log4j,您还可以配置实际写出哪些日志级别(信息,跟踪,警告,错误,调试是可用的默认级别)。

如果您有静态方法,则最好的办法是配置一个指向标准输出,文件等的记录器,但是您记录的所有内容都将存放在同一位置。使用记录器对象,创建起来更容易,因此您的日志记录信息可以散布到多个文件中。


谢谢。这也有助于理解何时使用静态方法。
严苛的古塔2015年

2
虽然我更喜欢实例化一个对象来进行日志记录,但是如此处所示,它是静态访问它而不是将其传递到每个方法调用中的,这是很常见的(我想说是更可取的)。日志记录本质上只是全球性的。
Chad Schouggins

还要注意的是,有时我们可能需要通过扩展记录器(或提供某些接口的实现并将其提供给记录器)来配置记录器。这将被用来做一些事情,比如改变日志记录的目的地(超出配置文件的允许范围)。但是,您可能会将特定实例设为静态,如@ChadSchouggins所述。
2015年

2

Logger.new是一个工厂,将使用该工厂使用结果(类/文件的名称)。

然后,您可以在配置文件中确定要记录的级别,而对于程序的某些部分完全不需要记录,而不必重新编译项目。

因此,您可以为发行版本禁用除高级日志记录(错误)之外的所有日志记录,并且仅激活要调试的部件的最低级别。


2

应尽可能避免静态方法调用。它是适当的依赖注入的过时替代方案,在更大的代码库中没有帮助。

例如,考虑可测试性。静态调用日志将使受测对象处于使用哪种日志类的控制之下-没有控制反转。这里不可能注入模拟对象或任何形式的伪造品。通过将记录器注入SUT,您将发现可以模拟记录器并将其注入。

当然,在讨论中使用DI代替静态方法调用的好处当然也超出了可测试性。考虑一下,如果您希望系统中有两个不同的记录器,将会发生什么情况,并考虑通过仅配置对象图而不更改现有代码来更改应用程序行为的选项。

总的来说,我建议您尝试一种DI方法,这样以后您就不会发现您的代码不可测试且难以处理。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.