Тернарная операция в Java - это не злоупотребление?


Я думаю, что ниже код трудно понять. Я также считаю его нарушения тернарный оператор в Java.

String name = ((this.getAllNamesAsDelimitedString().contains(incomingName) ? 
               incomingName:
               (CollectionsUtils.isEmptyCollection(this.getEntityOperationMap()) ? 
               null : 
               this.getEntityOperationMap.get(incomingName))));

Выше getAllNamesAsDelimitedString вернется запятая (,) с разделителями строк.

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

Н. Б: есть еще вложенные тернарные условия в коде, который я только что захватили.

Есть ли общее правило, которое указывает на количество уровней тернарный оператор должен быть разрешен? Иными словами, любое положение, предусматривающее, когда вы должны разорвать ваши тернарный оператор для лучшей читаемости кода?



8594
46
задан 5 декабря 2011 в 06:12 Источник Поделиться
Комментарии
4 ответа

Да, это насилие.

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

Кроме того, эти типы вызовов (getAllNamesAsDelimitedString().содержит(incomingName) и (CollectionsUtils.isEmptyCollection(это.getEntityOperationMap()) обычно в конечном итоге получить использованы многократно, что приводит к сухости.

Кроме того, (это.getAllNamesAsDelimitedString().содержит(incomingName) нарушает закон Деметры (она имеет две точки), и выставляет то, что я предполагаю, что это базовый набор сущностей, как струна, без уважительной причины.

Поэтому, во-первых, я бы изменить (это.getAllNamesAsDelimitedString().содержит(incomingName) для этого.containsName(incomingName)

Что делает заявление:

String name = ((containsName(incomingName)) ? incomingName:
(CollectionsUtils.isEmptyCollection(this.getEntityOperationMap()) ?
null :
this.getEntityOperationMap.get(incomingName))));

Только немного лучше.

Я применил тот же рефакторинг к следующему троичной, путем введения hasOperations способ:

 private boolean hasOperations()
{
return !CollectionUtils.isEmptyCollection(this.getEntityOperationMap())
}

Что сейчас делает заявление:

String name = ((containsName(incomingName)) ? incomingName:
hasOperations() ? this.getEntityOperationMap.get(incomingName)) : null;

Опять же, немного лучше, но все равно невкусный.

Наконец, я заменю это для реального если..то

 private String getName(String incomingName)
{
if (containsName(incomingName))
return incomingName;
else
return hasOperations() ? getOperation(incomingName) : null;
}

48
ответ дан 5 декабря 2011 в 06:12 Источник Поделиться

Я думаю, важно отметить, что вложенные тернарные операторы могут быть отформатированы, чтобы хорошо выглядеть:

String name = isConditionA ? "first"
: isConditionB ? "second"
: isConditionC ? "third"
: "fourth";

Это не самый читаемый вариант в вашем случае, поскольку вы уже вызовы метода, но я думаю, что это лучше, когда условия сохраняются короткие и содержательные.

57
ответ дан 6 декабря 2011 в 12:12 Источник Поделиться

На мой взгляд, я бы пойти на больше ясности кода, чем при использовании загадочные тернарные операции. В тех случаях, когда троичный заявления оператора становится трудно понять, на первый взгляд, если бы..то было бы идеально. И тем более я не знаю никакой разницы в производительности в приложении с использованием тернарных операторов.
В ВЫ пример кода: это займет некоторое время, чтобы выяснить, что происходит с тернарным оператором, и даже с правильными отступами код не будет так очевиден, как с...если еще.

Может быть, вы могли извлекать пользу из соответствующей дискуссии здесь.

6
ответ дан 5 декабря 2011 в 06:12 Источник Поделиться

Я полностью согласен с пользователем @seand — форматирование делает все различия в мире. Я не думаю, что ваш пример злоупотреблений на всех, но я думаю, было бы легче следовать с небольшими изменениями...

Во-первых, убрать лишние скобки:

String name = this.getAllNamesAsDelimitedString().contains(incomingName) ? 
incomingName:
CollectionsUtils.isEmptyCollection(this.getEntityOperationMap() ?
null :
this.getEntityOperationMap.get(incomingName);

Далее, переформатировать тернарное дерево выражения как предложил @seand:

String name = this.getAllNamesAsDelimitedString().contains(incomingName) ? incomingName
: CollectionsUtils.isEmptyCollection(this.getEntityOperationMap() ? null
: this.getEntityOperationMap.get(incomingName);

Я часто нахожу его более читабельным на место ? и : только после того, как их предыдущий символ — без промежуточных пробелов — как если бы они были английской пунктуации:

String name = isConditionA? "first":
isConditionB? "second":
isConditionC? "third":
"fourth";

что даст:

String name = this.getAllNamesAsDelimitedString().contains(incomingName)? incomingName:
CollectionsUtils.isEmptyCollection(this.getEntityOperationMap()? null:
this.getEntityOperationMap.get(incomingName);

Но в этом случае, я бы, наверное, написать так:

String name =
this.getAllNamesAsDelimitedString().contains(incomingName)
? incomingName
: CollectionsUtils.isEmptyCollection(this.getEntityOperationMap()
? null
: this.getEntityOperationMap.get(incomingName);

3
ответ дан 22 января 2012 в 07:01 Источник Поделиться