これはもっと理論的な質問です。ロギングは、ロギングを主な目的としないクラス内に存在する必要がありますか?
これは、数値の計算を実行するものすべての簡単なインターフェイスです。
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を装飾するクラスを作成することで、ログをミックスに戻すことができますが、そうすると、ReallyIntenseCalculationのプライベートメソッド内で行われていたより詳細なログの一部が損なわれます。
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);
}
}
ロギングデコレータを持つことのその他の考えられる長所と短所は何ですか?