Используя тернарный оператор с 4 выражениями
Является ли это приемлемой практикой кодирования?
public class MessageFormat {
private static final Color DEFAULT_COLOR = Color.RED;
private Color messageColor = DEFAULT_COLOR;
public MessageFormat(Person person) {
Color color = person.getPreferredColor();
messageColor = (color != null) ? color : messageColor; // this line
}
}
или мне лучше пойти с классикой...
if (color != null) {
messageColor = color;
}
Ответы
Ответ 1
Использование оператора?: должно быть ограничено, чтобы сделать код более читаемым. Классический пример:
a = sprintf( "There are %i green bottle%s on the wall.", i, (i==1?"":"s") );
В этом случае код будет менее читаемым, если вы разделите его на 5 строк if/else.
Я обычно кладу скобки вокруг всего оператора, так что, читая его, я мысленно разбираю его как одно значение.
messageColor = (color != null ? color : messageColor);
Другой вариант
messageColor = color || messageColor;
Что на некоторых языках будет оценивать "цвет", если только цвет не соответствует "false", и в этом случае значение messageColor. По-моему, этого следует избегать, так как это может смутить людей.
Самое главное - быть последовательным, чтобы следующий человек, читающий ваш код (даже если он был), имел минимальные когнитивные издержки.
Ответ 2
Читаемость, легкость понимания и т.д. в этом случае одинаковы (я имею в виду, давай...). В первом примере мне не нравится дублирование и очевидное самоопределение; это перевело бы на что-то вроде:
if (colour != null) {messageColour = colour;}
else {messageColour = messageColour;};
что немного глупо.
Я обычно пишу второй в одной строке, но это вопрос индивидуальной фантазии и. правила стиля кодирования:
if (colour != null) {messageColour = colour;};
EDIT (теперь я более самоуверен, чем 8 лет назад)
Поскольку вы ищете лучшие практики:
// Use default visibility by default, especially in examples.
// Public needs a reason.
class MessageFormat {
static final Color DEFAULT_COLOR = Color.RED;
// Strongly prefer final fields.
private final Color messageColor;
// Protect parameters and variables against abuse by other Java developers
MessageFormat (final Person person) {
// Use Optionals; null is a code smell
final Optional<Color> preferredColor = person.getPreferredColor();
// Bask in the clarity of the message
this.messageColor = preferredColor.orElse(DEFAULT_COLOR);
}
}
Ответ 3
Использование тернарного оператора часто является чувствительной проблемой наряду с другими стандартами кодирования. Его использование, вероятно, лучше всего определяется стандартами кодирования на вашем сайте.
Однако в этой конкретной ситуации я определенно рекомендую второй вариант; это не только более ясно, но использование тернарного оператора здесь совершенно не нужно. Нет необходимости повторно назначать messageColor себе, поэтому единственной функцией тернарного оператора в этой конкретной ситуации является обфускация кода.
Ответ 4
Тернарный оператор более распространен среди программистов C. В C, если вы избегаете структур управления, вы можете часто получать более эффективную конвейерную обработку, поскольку предсказание ветвления не должно идти не так. Я сомневаюсь, что вы увидите разницу в производительности в Java, а шаблон if-null-then-assign намного чаще, чем тройной. Однако, если вы поддерживаете существующую базу кода, лучше всего оставаться в соответствии с существующим кодом.
Если вы много чего делаете, вы можете написать функцию defaultIfNull
, firstNonNull
или coalesce
, которая может сделать код еще более кратким. Apache Commons Lang включает функцию defaultIfNull
.
Некоторые языки включают оператор ||=
, который является обычной идиомой для значений по умолчанию на этих языках.
Ответ 5
Я предпочитаю второй, потому что он более четко выражает то, что вы имеете в виду: вы хотите изменить цвет только в том случае, если он не равен нулю. Первый метод не делает это настолько ясным.
Ответ 6
Тернарные операторы часто злоупотребляют, поскольку создаваемый ими код кажется умным и компактным.
Фактически они делают код менее читаемым и подвержены большей ошибке.
По возможности рекомендуется использовать более длинную версию
if ( <condition> ) {
<action> ;
}
Вместо тройного синтаксиса.
Ответ 7
В вашем случае я бы предпочел "классическую" реализацию, потому что мне быстрее понять, что вы хотите использовать только новый цвет, если у человека есть предпочтительный вариант.
Я иногда использую его в вызовах методов, если я хочу избежать NPE, но я обычно выравниваю эти уродливые фрагменты кода в одном из следующих рефакторингов;)
Ответ 8
Кажется, для меня это хорошо (я использую тройной оператор Python), но этот тип проблемы стиля, как правило, очень субъективен. Если проект имеет документ стиля кодирования, вы можете проверить его.