Стратегия возврата PHP. Один единственный тип или больше? - PullRequest
0 голосов
/ 25 июня 2018

Я строю большие php-приложения, но я знаю, что задаю себе вопрос: должна ли функция возвращать только один тип данных и нулевое ИЛИ нормально ли возвращать больше типов данных.Потому что теперь он начал чувствовать себя грязно, чтобы перенастроить более одного типа данных (кроме нуля), потому что он предлагает вам написать такие вещи после вызова функции:

if(is_array($returnVariable)) { 
    // do something
} else if(is_int($returnVarable)) { 
    // do something else
}

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

public function update(array $data, Model $user)
{
    if(!is_a($user, User::class)) return null;

    //Update the user
    $user->fill($data);

    //Send the user an activated notification if it was activated and it was not earlier.
    if($user->getOriginal('activated') == 0 && $user->activated == 1) {
        $user->activated_at = Carbon::now()->toDateTimeString();
        $user->notify(new ActivatedUserNotification($user));
    }

    $saved = $user->save();

    //User was not updated because of an error
    if(!$saved) return null;

    //User was successfully updated. Return the user
    return $user;
}

Я действительно хотел бы вернуть одну вещь или ноль.И я делаю это.Но так как я возвращаю несколько нулей, я не могу получить конкретную информацию, почему он возвратил ноль в том месте, где я вызываю эту функцию.Или это может быть признаком того, что функция нарушает что-то вроде принципа разделения интересов?У меня также есть другие случаи, подобные этому, поэтому, пожалуйста, не будьте слишком конкретны в решении этой конкретной функции.

Ответы [ 2 ]

0 голосов
/ 25 июня 2018

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

Если вы используете PHP 7, вы можете объявить тип возвращаемого значения следующим образом ...

function sum($a, $b): float {
    return $a + $b;
}

Это может помочь вам убедиться, что ваша функция не выполняетсяслишком много и сделать его более удобным для потребителя вашего класса.

У него есть ограничения.В PHP нет ( co / contra variance ) (пока), поэтому существуют ситуации (например, интерфейс), в которых подсказки типов фактически будут препятствовать простоте вашего API. Кроме того, есть случаи, когда вы можете захотеть использовать универсальный в качестве типа возврата.Они также еще не являются частью PHP, поэтому в тех случаях, когда вы хотите использовать универсальный тип в качестве подсказки типа, вам пока придется жить без подсказки типа.

Похоже, у вас естьобратил внимание на некоторые преимущества уже используемого типа возврата, а также преимущества использования типа параметра.

Использование параметров ввода совершенно очевидно: оно уменьшает сложность функции и делает ее склонной кделая одну краткую вещь.

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

Простой пример ...

function add($a, $b) {
  if (is_string($a) && is_string($b)) {
    return $a . $b;
  } else if (is_int($a) && is_int($b)) {
    return $a + $b;
  }
}

Эта функция не вводит свои параметры, поэтому нам нужно подумать о ее общих случаях использования и обработать различные типы параметров в функции.Это лишает нашу функцию фокуса, и мы никогда не обнаружим все возможные случаи, то есть функция, скорее всего, сломается, а затем увеличится в объеме.

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

$result = add($a, $b);
if (is_string($result)) {
  // Do something
} else if (is_int($result)) {
  // Do something else
}

Мы можем исправить это:

function add(Int $a, Int $b) : Int {
    return $a + $b;
}
function concatStrings(String $a, String $b) : String {
    return $a . $b;
}

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

0 голосов
/ 25 июня 2018

В PHP НОРМАЛЬНО для функции возвращать более одного типа.strpos является примером.Возвращает целое число или логическое значение.Вы должны быть готовы сказать разницу между целым нулем или логическим ложным.

...