Используя тернарный оператор с 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), но этот тип проблемы стиля, как правило, очень субъективен. Если проект имеет документ стиля кодирования, вы можете проверить его.