Это скорее теоретический вопрос. Должна ли регистрация выполняться внутри класса, для которого основная цель не регистрируется?Должна ли регистрироваться в классе, который не предназначен для регистрации?
Вот простой интерфейс для всего, что будет заготовлять расчет по числу.
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);
}
}
Каковы другие возможные плюсы и минусы использования декоратора лесозаготовок?
Если это часть реализации, то это должен быть параметр конструктора. В противном случае, как кто-то смотрит на API, который должен знать, и что, если пользователь не хочет использовать другой регистратор. –