이것은 이론적 인 질문입니다. 로깅이 주 목적 인 클래스 내에 로깅이 있어야합니까?로깅이 아닌 주 목적의 클래스 내에 로깅이 있어야합니까?
다음은 숫자에 대한 계산을 수행 할 간단한 인터페이스입니다.
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을 꾸미는 클래스를 작성하면 Login을 믹스에 다시 추가 할 수 있지만 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);
}
}
로깅 데코레이터를 사용하는 다른 장단점은 무엇입니까?
구현의 일부인 경우에는 생성자 매개 변수 여야합니다. 그렇지 않으면, API를 보는 사람은 어떻게 알 수 있습니까? 사용자가 다른 로거를 사용하고 싶지 않은 경우 어떻게됩니까? –