Использование троичного оператора с 4 выражениями - PullRequest
11 голосов
/ 29 ноября 2009

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

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;
}

Ответы [ 8 ]

24 голосов
/ 29 ноября 2009

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

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. На мой взгляд, этого следует избегать, поскольку это может смутить людей.

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

4 голосов
/ 29 ноября 2009

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

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);
    }
}
2 голосов
/ 29 ноября 2009

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

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

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

2 голосов
/ 29 ноября 2009

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

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

1 голос
/ 29 ноября 2009

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

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

1 голос
/ 29 ноября 2009

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

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

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

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

1 голос
/ 29 ноября 2009

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

0 голосов
/ 29 ноября 2009

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

...