记录和dependency injection

我尝试基于Java构建和应用程序。

对于dependency injection,我使用Google Guice。

现在我想出了在应用程序期间记录一些信息的问题。 我不会以方法调用等方式谈论一般日志记录。我知道AOP ,我可以像方法调用跟踪那样做。

我要找的是手动记录。 我需要一些方法来记录我的应用程序中的每个类。 所以我想到了两个选择:

  1. 通过使用Guice注入框架通过构造函数(或者setter或private …)来获取记录器,但感觉就像将记录问题真正添加到每个类并污染我的构造函数
  2. 在我想要调用日志的方法中使用全局服务定位器。 呃,但所有DI粉丝都会因为这样做而讨厌我

那么从实际的角度来看,最好的方法是什么?

我需要一些方法来记录我的应用程序中的每个类。

再想一想。 如果您认为几乎每个class级都需要登录,那么您的设计就会出现问题。 此Stackoverflow答案谈论了您的设计可能出现的问题。 它在.NET的上下文中得到了回答,但答案也适用于Java。

该答案主要讨论exception日志记录,对于非exception日志记录,我会说:防止在太多地方记录太多信息。 对于您要记录的每个信息或警告,首先询问这是否应该是一个例外。 例如,不要记录“我们不应该在这个分支中”之类的东西,而是抛出exception!

即使你想记录调试信息,有没有人会读这个? 你最终会得到包含成千上万行的日志文件,没有人会阅读。 如果他们阅读它,他们必须浏览所有这些文本行,并通过它进行复杂的正则表达式搜索,以获取他们正在寻找的信息。

我看到开发人员这样做的另一个原因是掩盖他们糟糕的代码。 正如评论以这种方式使用一样。 我看到开发人员记录了“我们已执行此块”或“如果跳过分支”这样的事情。 通过这种方式,他们可以追溯代码和大方法。

但是,我们现在都知道方法应该很小 ,而不是编写大方法。 不,甚至更小。 此外,如果您对代码进行彻底的unit testing,则没有太多理由对代码进行调试,并且您已经validation它可以执行它应该执行的操作。

再好的设计可以帮到这里。 当您使用Stackoverflow应答(使用命令处理程序)中所述的设计时,您可以再次创建一个装饰器,它可以序列化任何任意命令消息并在执行开始之前将其记录到磁盘。 这为您提供了非常准确的日志。 只需将一些上下文信息(例如执行时间和用户名)添加到日志中,您就可以获得审计跟踪,甚至可以在调试甚至负载测试期间用于重放命令。

我现在使用这种类型的应用程序设计已有几年了,从那时起,我几乎没有理由在业务逻辑中进行额外的日志记录。 它偶尔需要,但这些情况非常罕见。

但感觉就像真正为每个类添加日志记录问题并污染我的构造函数

确实如此,你最终会得到参数太多的构造函数。 但不要怪记录器,责怪你的代码。 您在此违反了单一责任原则 。 您可以通过静态外观调用它来“隐藏”此依赖关系,但这不会降低依赖项的数量和类的整体复杂性。

在我想要调用日志的方法中使用全局服务定位器。 呃,但所有DI粉丝都会因为这样做而讨厌我

最后,你会讨厌自己,因为每个类仍然有一个额外的依赖(在这种情况下一个很好的隐藏依赖)。 这使得每个类更复杂,并将迫使您拥有更多代码:更多代码要测试,更多代码有bug,需要维护更多代码。