Как избежать утомительных проверок объекта на null

Если у меня есть класс, который я хочу принять необязательного регистратора для регистрации отладочной информации:

public class A {

private Logger logger ; 

public A( Logger logger ) { 
    this.logger = logger ; 
}

public A() { 
    this( null ) ;
}

public void hello() {
    logger.debug( "hello" ) ;
}

public void goodbye() {
    logger.warn( "goodbye" ) ; 
}

}

Есть ли способ избежать необходимости постоянных нулевых проверок?

public void hello() {

    if( logger != null ) { 
        logger.debug( "hello" ) ;
    }

}

public void goodbye() {

    if( logger != null ) {
        logger.warn( "goodbye" ) ; 
    }

}

Я подумал, может быть, если бы я создал класс-оболочку регистратора, он мог бы выполнять проверки для меня, а затем либо ничего не делать, либо регистрировать сообщение. Но тогда мне нужно было бы обернуть каждый метод, который я хотел бы использовать.


person CrazyPenguin    schedule 07.02.2011    source источник
comment
Предполагается ли, что для регистратора можно установить значение null? Или вы просто защитный код? Является ли нулевой регистратор способом, которым вы хотите отключить ведение журнала?   -  person Bert F    schedule 08.02.2011
comment
Это предназначено, да; Я хотел бы создать объект, который будет выводить сообщения с помощью регистратора, если он предоставлен, но ничего не выводить, если его нет.   -  person CrazyPenguin    schedule 08.02.2011
comment
снова создайте собственный импл, у которого все warn/info/debug методы полностью пусты.   -  person bestsss    schedule 08.02.2011


Ответы (7)


Я бы создал Logger в качестве интерфейса и реализовал настоящий регистратор и фиктивный класс, который ничего не регистрирует. Таким образом, вы всегда можете просто получить доступ к регистратору без каких-либо нулевых проверок.

person Amir Rachum    schedule 07.02.2011

Все ответы в основном предлагают использовать шаблон Null Object, см.:

person Tomasz Nurkiewicz    schedule 07.02.2011

2 вещи:

  1. always initialize the logger
  2. (and/or) use a sentinel logger that doesn't to anything at all
person bestsss    schedule 07.02.2011

Что-то вроде этого, может быть:

private void logDebug(final String str, final Object ... parameters ) {
    if (this.logger != null && this.logger.isDebugEnabled()) {
        this.logger.debug(
           parameters.length > 0
              ? MessageFormat.format(str, parameters)
              : str
        );
    }
}

private void logInfo(final String str,final Object ... parameters) {
    if (this.logger != null && this.logger.isInfoEnabled()) {
        this.logger.info(
           parameters.length > 0
              ? MessageFormat.format(str, parameters)
              : str
        );
    }
}

Теперь вы можете просто вызвать logDebug(str) или logInfo(str), а также интерполировать сообщения журнала с параметрами, используя MessageFormat.format():

logDebug("Called {0} method with parameters {1} and {2}","doStuff",foo,bar);
person Sean Patrick Floyd    schedule 07.02.2011

Извините, если это звучит глупо, но разве методы Warn и Debug static не решат эту проблему? Если вам нужен экземпляр, просто создайте его внутри статических методов или, если это одноэлементная проверка на нуль внутри статических методов.

person Fabio    schedule 22.07.2011
comment
Точно, знаменитый шаблон singleton :-) - person Anders R. Bystrup; 16.11.2012

Вы можете установить для логического параметра enableLogging значение true в конструкторе с 1 параметром и значение false в пустом конструкторе. Таким образом вы придаете больше смысла своим проверкам - и они быстрее.

person Dunaril    schedule 07.02.2011

Основная проблема заключается в том, что вы везде используете null, а это означает, что вам, естественно, нужно везде проверять наличие null. Создайте Logger, в котором все методы ничего не делают, и используйте этот экземпляр там, где это уместно.

person mP.    schedule 07.02.2011