记录和依赖注入

Sim*_*awk 11 java logging dependency-injection service-locator

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

对于依赖注入,我使用Google Guice.

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

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

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

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

Ste*_*ven 19

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

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

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

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

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

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

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

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

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

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

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

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