Как вы называете этот (анти?) шаблон, где каждая операция возвращает экземпляр класса результата?

У следующего (анти?) Шаблона есть имя?

  • каждая функция возвращает экземпляр result класс (или структура, или ассоциативный массив), который имеет по крайней мере эти две открытые переменные:
    • success: значение true / false для удержания, если действие успешно завершено
    • result: переменная, которая содержит результат функции или ничего, если функция void.
  • если success является false error переменная может содержать информацию (исключение / трассировка стека / отладка) об ошибке
  • message переменная, содержащая удобное для пользователя сообщение, может быть определена, если error не пусто
  • только результат операции инкапсулируется. Входы передаются нормально.

Я видел это как в .Net, так и в PHP (на сервере и в скрипте, вызываемом запросами JavaScript / Ajax). Это лучшая практика? Это анти-паттерн?

-1

Решение

Это распространенный способ обработки вызова процедуры, который может возвращать как ошибку, так и успех, и значение. Как отмечено в комментариях, это довольно распространено при вызове API. Альтернативы включают в себя: а) объединение возвращаемого значения с успехом / неудачей, чтобы его нужно было знать и проверять извне в вызывающем коде, б) использование параметра out для возврата желаемого значения в случае успеха, или в) создание исключений для указания сбоя , что дорого и глупо, поэтому я не буду обсуждать дальше.

а) Объединение возвращаемого значения с успехом / неудачей

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

public string GetSomeString(int id)
{
//return a value on success or null on failure
}

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

var result = obj.GetSomeString(2);
if(string.IsNullOrEmpty(result))
{
//ooops, failed
}

И это, конечно, не вариант, если null является допустимым возвращаемым значением.

Точно так же для вызова int …

public int GetSomeInt(string someArg, bool someOtherArg)
{
//return a value or a -1 for failure
}

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

 var result = obj.GetSomeInt("blah", true);
if(result == -1)
{
//ooops, failed
}

И опять же, не работает, если ваше значение «error» является допустимым в некоторых случаях (или, что еще хуже, становится допустимым в более позднее время).

б) Использование параметра out для возврата значения в случае успеха

Другой вариант — возвратить успех или неудачу из метода и использовать параметр out, чтобы вернуть значение в случае успеха.

public bool GetSomeString(int id, out string someString)
{
//if fail return false
//otherwise set someString = value and return true
}

Таким образом, код вызова выглядит следующим образом …

string goodString = null;
if(!obj.GetSomeString(2, out goodString))
{
//ooops, something bad happened
}

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

Использование объекта Result

Это дает вам преимущество б) в том, что успех / сбой однозначно очевиден и не требует, чтобы вызывающий код знал, какое возвращаемое значение может указывать на сбой. Он выглядит чище, потому что не требует использования синтаксиса out. Это также дает дополнительное преимущество, позволяя вам указать причину сбоя, передав ее обратно в свойстве сообщения объекта результата.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]