Здравствуйте,
Допустим, нужно проверить, можно ли отправить сообщение пользователю, и если нет, вывести соответствующее сообщение с указанием причины (пример просто один из, т.е. могут быть другие похожие задачи и хочется выбрать типовое решения для использования в проекте).
Представим такую функцию на PHP:
function CanSendMessageToUser(User $user)
{
if(!$user->AccountEnabled)
{
return ...; // вызывающему коду нужно сообщить, что сообщение отправить нельзя потому что пользователь уже неактивен (заблокирован и т.п.)
}
else if(/* some other check */)
{
return ...; // вызывающему коду нужно сообщить, что сообщение отправить нельзя еще по какой-то причине
}
return ...; // сообщение можно отправить
}
У нас есть такие основные варианты:
1) Использовать исключения. Просто, мало кода, но почему-то мне кажется что не очень кошерно использовать тут исключения (наверное потому что исключения я привык использовать для каких-то исключительных ситуаций, которые не должны происходить в нормальном режиме работы).
2) Использовать коды ошибок и функцию для преобразования кода ошибки в текст:
function CanSendMessageToUser(User $user)
{
if(!$user->AccountEnabled)
{
return SendMessageTestResult::ACCOUNT_DISABLED;
}
...
return SendMessageTestResult::SUCCESS;
}
class SendMessageTestResult
{
const SUCCESS = 0;
const ACCOUNT_DISABLED = 1;
...
}
function SendMessageErrorCodeToText($errorCode)
{
switch($errorCode)
{
case SendMessageTestResult::ACCOUNT_DISABLED:
return 'Cannot send message to the user because their account is disabled.';
...
}
}
//Вызывающий код получается чистеньким:
$res = CanSendMessageToUser($user);
if($res !== SendMessageTestResult::SUCCESS)
return Presenter::GetErrorMessage(SendMessageErrorCodeToText($res));
Минус такого варианта, в том что как-то много кода нам приходится писать (класс с константами кодов ошибок и функцию-конвертер кода ошибки в текст).
3) Возвращать константу SUCCESS или текст ошибки:
function CanSendMessageToUser(User $user)
{
if(!$user->AccountEnabled)
{
return 'Cannot send message to the user because their account is disabled.';
}
...
return SUCCESS;
}
...
$res = CanSendMessageToUser($user);
if($res !== SUCCESS)
return Presenter::GetErrorMessage($res);
Чистенько и простенько, но минус в неуниверсальности, т.е. если вызывающему коду нужно будет не просто показать пользователю сообщение, а в зависимости от ошибки предпринять какие-то действия, то он этого сделать не сможет.
4) Использовать специальный класс типа MethodResult, описывающий результат выполнения метода, и который может содержать код ошибки или описание ошибки:
function CanSendMessageToUser(User $user)
{
if(!$user->AccountEnabled)
{
return MethodResult::ErrorMessage('Cannot send message to the user because their account is disabled.');
}
...
return MethodResult::Success();
}
...
$res = CanSendMessageToUser($user);
if(!$res->Success)
return Presenter::GetErrorMessage($res->ErrorMessage);
Вроде интересный вариант, но во-первых мне начинает казаться что это самодельное исключение

, и во-вторых вызывающему коду нужно знать в каком виде будет представлена ошибка: в виде кода или текста (что впрочем не кажется мне особой проблемой).
---
Что скажут гуру дизайна и PHP?