2015-08-19 3 views
3

Работа с Hibernate я использую этот вид кода много раз:элегантный способ проверить нуль

int someId = entity.getSomething() == null ? null : entity.getSomething().getId(); 

Этот код становится немного более грязным при попытке применить на более иерархии:

int someId = entity.getParent() == null ? null : 
entity.getParent().getParent() == null ? null : 
entity.getParent().getParent().getSomething() == null ? null : 
entity.getParent().getParent().getSomething().getId(); 

Есть ли более элегантный способ сделать это?

+2

Java 8 в 'Optional.flatMap', может быть. –

+6

Вы должны избегать вызовов метода цепочки типа 'entity.getParent(). GetParent(). GetSomething().getId() ', потому что« общение с незнакомцами »делает код жестко связанным и, следовательно, сложнее рефакторировать. См. Также: [Закон Деметры] (https://en.m.wikipedia.org/wiki/Law_of_Demeter). –

+0

Еще одна вещь, которая помогает: если ваш метод имеет свойство инварианта, которое он никогда не возвращает null, вам не нужно его проверять. Не позволяйте вещам быть обнуляемыми, если они действительно не должны быть. – drrob

ответ

1

Читаемость является очень важным фактором, а также упрощением кода. Здесь лучше использовать простое условие if.

if(entity.getParent()!=null && entity.getParent().getParent() !=null && 
    entity.getParent().getParent().getSomething()!=null && 
       entity.getParent().getParent().getSomething().getId()!=null){ 


} 

И из-за && («короткое замыкание и»), если одно условия false не другое условия в right выполнении.

+3

Прошу прощения, но вы думаете, что это построение 'if' является читаемым? :) –

+0

@RafaelOsipov да –

+0

Я согласен с @RafaelOsipov, это очень сложно прочитать, если строительство –

0

Вы назначаете такое же значение null, если оно равно null.

Почему бы вам не попробовать, если он не является нулевым.

if(x != null) x = y 
0

Есть ли более элегантный способ сделать это?

Вы можете просто пойти на примерки улова для проверки нулевой:

try{ 
    int id = entity.getParent().getParent().getSomething().getId(); 
    // do something with id 
} catch(NullPointerException ex) { 
    // got null 
} 
+4

Управление исполнением - плохой способ программирования. –

+0

@UmaKanth, OP ищет более читаемый код, я считаю его хорошей практикой, а не такими уродливыми блоками кода – Arvind

+0

, если возврат null здесь является ошибкой, тогда это хороший способ. –

2

В случае эти объекты сущностей написаны самостоятельно, а не в библиотеке, я хотел бы рассмотреть рефакторинг их и использовать NullObjects. Таким образом, вы можете напрямую позвонить

Integer someId = entity.getParent().getParent().getSomething().getId(); 

как это затем вернет ваше нулевое целое число.

В принципе, это работает так:

  1. entity.getParent() возвращает экземпляр NullParent
  2. этот NullParent класс имеет метод GetParent(), который также будет возвращать NullParent экземпляр
  3. опять же, этот класс NullParent имеет метод getSomething(), который вернет экземпляр NullSomething
  4. класс NullSomething имеет метод getId(), который, наконец, вернет ваше нулевое целое число (например, 0 или другой объект NullInteger).

Вот интересный пост на Why NULL is bad?

5

Как на комментарий Луи Вассермана, Optional почти можно использовать как раствор А, NullObject a'la flogy в.

Использование Java 8 Optional и лямбды это выглядит так

Integer value = Optional.ofNullable(entity) 
         .map(Entity::getParent) 
         .map(Entity::getParent) 
         .map(Entity::getSomething) 
         .map(Something::getId) 
         .orElse(null); 
+0

Был немного смущен этим ответом - используя :: без ничего, прежде чем указывать класс, не скомпилируется правильно? – 755

+0

@ 755 Да, вы правы - похоже, что я неправильно читал с другого языка, где этот тип был выведен - извините за путаницу. Я обновил ответ, чтобы использовать правильные имена классов. –

Смежные вопросы