Использование троичного оператора с 4 выражениями

StackOverflow https://stackoverflow.com/questions/1815187

Вопрос

Это приемлемая практика кодирования?

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;
}
Это было полезно?

Решение

Использование оператора?: должно быть ограничено, чтобы сделать код более читабельным. Классический пример:

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;

Который на некоторых языках будет оцениваться как «цвет», если только цвет не оценивается как «ложный», в этом случае значение messageColor. На мой взгляд, этого следует избегать, так как это может смутить людей.

Самое главное - быть последовательным, чтобы у следующего человека, читающего ваш код (даже если это вы), были минимальные когнитивные издержки.

Другие советы

Читаемость, простота понимания и т. д. в этом случае одинаковы (я имею в виду, давай ... ). Мне не нравится дублирование и очевидное самоопределение в первом примере; это будет означать что-то вроде:

if (colour != null) {messageColour = colour;}
   else {messageColour = messageColour;};

что немного глупо.

Обычно я пишу второе в одной строке, но это вопрос индивидуальной фантазии, соответственно. рекомендации по стилю кодирования:

if (colour != null) {messageColour = colour;};

РЕДАКТИРОВАТЬ (сейчас я более самоуверен, чем 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);
    }
}

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

Однако в этой конкретной ситуации я бы определенно рекомендовал второй вариант; это не только более понятно, но и использование тернарного оператора здесь совершенно не нужно. Нет необходимости переназначать messageColor для себя, поэтому единственной функцией троичного оператора в этой конкретной ситуации является запутывание кода.

Тернарный оператор более распространен среди программистов на Си. В C, если вы избегаете управляющих структур, вы можете получить лучшую конвейерную работу, так как нет предсказания ветвления, которое могло бы пойти не так. Я сомневаюсь, что вы увидите какие-либо различия в производительности в Java, и шаблон if-null-then-assign гораздо более распространен, чем троичный. Однако, если вы поддерживаете существующую кодовую базу, обычно лучше оставаться в соответствии с существующим кодом.

Если вы часто этим занимаетесь, вы можете написать функцию defaultIfNull , firstNonNull или coalesce , которая может сделать код еще более кратким. Apache Commons Lang включает функцию defaultIfNull .

В некоторых языках есть оператор || = , который является обычной идиомой для значений по умолчанию в этих языках.

Я предпочитаю второе, потому что оно более четко выражает то, что вы имеете в виду: вы хотите изменить цвет, только если он не нулевой. Первый метод не делает это настолько ясным.

В вашем случае я бы предпочел «классическую» реализацию, потому что для меня быстрее понять, что вы хотите использовать новый цвет, только если у человека есть предпочтительный.

Я иногда использую его в вызовах методов, если я хочу избежать NPE, но я обычно выявляю эти уродливые фрагменты кода в одном из следующих рефакторингов;)

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

Фактически они делают код менее читаемым и более подверженным ошибкам. По возможности рекомендуется использовать более длинную версию

 if ( <condition> ) {
     <action> ;
 }

Вместо троичного синтаксиса.

Мне кажется, это нормально (я часто использую троичный оператор Python), но этот тип стилей обычно очень субъективен. Если у проекта есть документ в стиле кодирования, вы можете проверить это.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top