Я называю это шаблоном проектирования регистратора:)
Нам повезло, что у нас есть API Logger (slf4J), который позволяет нам выбирать реализацию по своему усмотрению, мне особенно нравится loggback, поскольку он предлагает простую предварительную настройку.
Один трюк, который я использую при работе с абстракцией классов и наследованием, – это ведение журнала с использованием конкретного класса, а не с использованием какого-либо родительского регистратора.
Я нашел два основных способа передать регистратор, чтобы убедиться, что я регистрируюсь, используя правильный экземпляр регистратора.
Регистраторы статичны
public abstract class Parent { private static final Logger log = LoggerFactory.getLogger(Parent.class); protected void doSomething() { // will log using this class Logger log.info("Success"); } }
Мое типичное сообщение в журнале будет следующим:
04-07-2019T11:00:00.662 [main] INFO Parent.doSomething Success
У нас есть некоторые методы по умолчанию, которые мы хотели бы использовать в наших унаследованных классах. Но теперь любой унаследованный класс будет регистрироваться с помощью регистратора родительского класса.
public class Child extends Parent { private static final Logger log = LoggerFactory.getLogger(Child.class); protected void doSomethingElse() { // will log using this class Logger log.info("Some message"); doSomething(); // will log using parent logger } }
Теперь журнал поступает из двух разных классов, использующих два разных регистратора
04-05-2019T11:11:00.662 [main] INFO Child.doSomethingElse Some Message 04-05-2019T11:11:00.662 [main] INFO Parent.doSomething Success
Будет полезно иметь оба сообщения журнала с одним и тем же сообщением дочернего класса, поскольку у нас может быть много производных классов, и нам нужно знать исходный вызывающий doSomething()
Переопределение конструктора
Мы можем разрешить производным классам передавать регистратор в конструктор:
public abstract class Parent { private final Logger logger; public Parent(Logger logger) { this.logger = logger; } protected void doSomething() { // will log using the injected Logger instance log.info("Success"); } }
Наш дочерний класс должен будет передать статический экземпляр регистратора нашему родительскому классу
public class Child extends Parent { private static final Logger log = LoggerFactory.getLogger(Child.class); public Child() { super(log); } protected void doSomethingElse() { // All logging will be done using this instance Logger log.info("Some message"); doSomething(); } }
В журнале теперь будет указано имя дочернего класса.
04-05-2019T11:21:00.332 [main] INFO Child.doSomethingElse Some Message 04-05-2019T11:21:00.332 [main] INFO Child.doSomething Success
Переопределение метода
В этом случае мы могли бы захотеть смешать два регистратора, где часть ведения журнала будет выполняться с помощью родительского регистратора, а часть – с помощью нашего дочернего класса. Мы можем передать экземпляр регистратора вызову родительского метода.
public abstract class Parent { protected void doSomething(Logger log) { // will log using the injected Logger instance log.info("Success"); } }
А в дочернем классе нам больше не нужен конструктор и мы просто передаем Регистратор методу.
public class Child extends Parent { private static final Logger log = LoggerFactory.getLogger(Child.class); protected void doSomethingElse() { // All logging will be done using this instance Logger log.info("Some message"); doSomething(log); // we pass the logger to the method } }
В журнале теперь будет указано имя дочернего класса.
04-05-2019 11:31:00.100 [main] INFO Child:doSomethingElse Some Message 04-05-2019 11:31:00.100 [main] INFO Child:doSomething Success
Смешивайте и сочетайте
Есть много способов реализовать эти идеи с помощью регистратора по умолчанию и передать регистратор, поэтому я просто описал крайние случаи. Вы можете смешивать и сочетать эти две идеи самыми разными способами.
Если вы найдете другие идеи полезными, пожалуйста, поделитесь ими в комментариях.
Надеюсь, вы найдете этот короткий пост полезным.
Спасибо за чтение.
Оригинал: “https://dev.to/gadeichhorn/pass-the-logger-445a”