Заранее извините, я просто не знаю, как сформулировать этот вопрос и как его искать. Я чувствую, что для этого должно быть название, какой-то принцип или проблема, но я этого не знаю. Мое название, вероятно, тоже не имеет смысла, но я надеюсь, что оно даст достаточный намек.

Я хочу решить, как структурировать свой код для проекта. В частности, вложенные условия. В случаях, когда вы не можете соединить их вместе, используя AND и т. Д.

sell_insurance($person): bool {
    if ($person->healthy() === true) {
        if ($person->rich() === true) {
            print 'sold!';
            return true;
        }
        print 'not enough money';
        return false;
    }
    print 'too risky to sell';
    return false;
}

Против:

sell_insurance($person): bool {
    if ($person->healthy() !== true) {
        print 'too risky';
        return false;
    }
    if ($person->rich() !== true) {
        print 'too poor';
        return false;
    }
    print 'sold!';
    return true;
}

Я думаю, что последнее легче читать, и если бы было около 50 вложенных if, это было бы просто некрасиво. Но я хочу быть уверенным, что не столкнусь с проблемами в будущем. Что-то неожиданное, я не увижу отсюда.

Эти тесты просты. Я опасаюсь одного: not(not a) не обязательно равно a. Иногда мы можем ожидать, что логика будет логической, хотя на самом деле это может быть не так. Я мог бы протестировать person->healthy() !== false, но мог бы не осознавать, что вместо true это может быть строка 'almost'. Или что-то менее глупое.

Еще меня беспокоит, как это выразить? Последняя структура по умолчанию равна true. Это кажется менее безопасным, чем первый подход.

Вопрос к кому-то с большим опытом - каковы преимущества / недостатки каждого подхода? Какой структуры вы придерживаетесь или перетасовываете? Спасибо

Я изучаю PHP, но полагаю, это более или менее применимо к любому языку.

1
Dwarf Vader 13 Мар 2018 в 18:21

2 ответа

Лучший ответ

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

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

$var= $person->healthy() ? 'true' : 'false';
 $var.=$person->rich() ? 'true' : 'false';

    switch ($var) {
case "truetrue":
 echo "SOLD!";
    break;
case "falsetrue":
 echo "too risky to sell";
    break;
case "truefalse":
 echo "too poor!";
    break;
default:
    echo "NO WAY!";
}

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

if ($person->healthy() && $person->rich()) {
   print "SOLD!";
    return true;
} elseif($person->healthy()) {
    print "too poor...";
     return false;
} elseif($person->rich()) {
    print "too risky...";
     return false;
} else {
    print "NO WAY!";
     return false;
}
1
holden 14 Мар 2018 в 10:14

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

Первый подход указывает на то, что вы ДОЛЖНЫ быть здоровым, чтобы получить этот предмет, с другой стороны, второй просто добавляет к нему некоторую логику (это может не иметь смысла)

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

1
Kolos Feri Fazekas 13 Мар 2018 в 15:34