这更像是一个理论问题。日志记录应该驻留在一个主要目的不是日志记录的类中吗?
这是一个简单的界面,用于对数字进行计算的任何内容。
public interface ICalculation {
public int calculate(int number);
}
这是执行计算并进行一些日志记录的 ICalculation 接口的实现。我相信这是一种非常务实的做法。除了构造函数接受我们通常不希望在计算域中看到的东西之外,内联日志记录可以说是非侵入性的。
public class ReallyIntenseCalculation : ICalculation {
private readonly ILogger log;
public ReallyIntenseCalculation() : this(new DefaultLogger()) {
}
public ReallyIntenseCalculation(ILogger log) {
this.log = log;
log.Debug("Instantiated a ReallyIntenseCalculation.");
}
public int calculate(int number) {
log.Debug("Some debug logging.")
var answer = DoTheDirtyWork(number);
log.Info(number + " resulted in " + answer);
return answer;
}
private int DoTheDirtyWork(int number) {
// crazy math happens here
log.Debug("A little bit of granular logging sprinkled in here.");
}
}
从 RealIntenseCalculation 中删除所有日志记录代码后,代码现在似乎具有明确的单一职责。
public class ReallyIntenseCalculation : ICalculation {
public int calculate(int number) {
return DoTheDirtyWork(number);
}
private int DoTheDirtyWork(int number) {
// crazy math happens here
}
}
好的,所以我们删除了真正强烈计算的记录其内部的能力。我们怎样才能找到一种方法来外部化该功能。输入装饰器模式。
通过创建一个装饰 ICalculation 的类,我们可以将日志重新添加到组合中,但这样做会损害在真正强烈计算的私有方法中发生的一些更精细的日志记录。
public class CalculationLoggingDecorator : ICalculation {
private readonly ICalculation calculation;
private readonly ILogger log;
public CalculationLoggingDecorator(ICalculation calculation, ILogger log) {
this.calculation = calculation;
this.log = log;
log.Debug("Instantiated a CalculationLoggingDecorator using " + calculation.ToString());
}
public int calculate(int number) {
log.Debug("Some debug logging.")
var answer = calculation.calculate(number);
log.Info(number + " resulted in " + answer);
}
}
拥有日志装饰器还有哪些其他可能的优点和缺点?