這更像是一個理論問題。如果日誌記錄駐留在主要目的不在日誌中的類中,如果日誌記錄駐留在主要目的不在記錄的類中?
這是一個簡單的接口,用於對數字進行預計算。
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.");
}
}
從ReallyIntenseCalculation刪除所有日誌代碼後,該代碼現在有什麼似乎是一個明確的單一職責。
public class ReallyIntenseCalculation : ICalculation {
public int calculate(int number) {
return DoTheDirtyWork(number);
}
private int DoTheDirtyWork(int number) {
// crazy math happens here
}
}
好吧,所以我們已經刪除了ReallyIntenseCalculation記錄其內部的能力。我們如何找到一種外部化該功能的方法。輸入裝飾者模式。
通過創建一個裝飾ICalculation的類,我們可以將日誌記錄添加到混合中,但這樣做會影響ReallyIncencalCalculation的私有方法中發生的一些更細化的日誌記錄。
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);
}
}
有一個記錄裝飾者的其他可能的利弊有哪些?
如果它是實現的一部分,那麼它應該是一個構造函數參數。否則,如何看待API的人意圖知道以及如果用戶不想使用不同的記錄器。 – 2011-05-24 01:01:20