Это проблема, с которой я сталкиваюсь довольно регулярно, и я никогда не обнаруживал / не выяснял ситуацию с лучшими практиками. Исключения - это, вероятно, путь, однако приложение, в котором я работаю, не использует их, поэтому я стараюсь придерживаться используемых в настоящее время методов.
Как лучше всего выложить, если необходимо проверить операторы, возвраты, сообщения и т. Д., Если требуется проверить 3, 4, 5 или более различных условий и установить либо сообщение об ошибке, либо обработка продолжается. Рекомендуется ли физически проверять все ошибки в начале кода?
Вот пример с некоторыми условиями типа реального мира.
function process($objectId,$userId,$newData)
{
$error = '';
if(($object = $this->getObject($objectId)) && $object->userOwnsObject($userId))
{
if($this->isValid($newData))
{
if($object->isWriteable())
{
if($object->write($newData))
{
// No error. Success!
}
else
{
$error = 'Unable to write object';
}
}
else
{
$error = 'Object not writeable';
}
}
else
{
$error = 'Data invalid';
}
}
else
{
$error = 'Object invalid';
}
return $error;
}
OR
function process($objectId,$userId,$newData)
{
$error = '';
if((!$object = $this->getObject($objectId)) && !$object->userOwnsObject($userId))
{
$error = 'Object invalid';
}
elseif(!$this->isValid($newData))
{
$error = 'Data invalid';
}
elseif(!$object->isWriteable())
{
$error = 'Object not writeable';
}
elseif(!$object->write($newData))
{
$error = 'Unable to write to object';
}
else
{
// Success!
}
return $error;
}
Мне ясно, что в этом случае вариант 2 - это путь. Это намного понятнее. Теперь мы можем сделать его немного сложнее:
function process($objectId,$userId,$newData)
{
$error = '';
if(($object = $this->getObject($objectId)) && $object->userOwnsObject($userId))
{
$this->setValidationRules();
$parent = $object->getParentObject();
$parent->prepareForChildUpdate();
if($this->isValid($newData,$parent))
{
$newData = $this->preProcessData($newData);
if($object->isWriteable())
{
// doServerIntensiveProcess() has no return value and must be done between these two steps
$this->doServerIntensiveProcess();
if($object->write($newData))
{
// No error. Success!
$parent->childUpdated();
}
else
{
$error = 'Unable to write object';
}
}
else
{
$error = 'Object not writeable';
}
}
else
{
$error = 'Data invalid';
}
}
else
{
$error = 'Object invalid';
}
return $error;
}
ИЛИ с некоторыми проблемами
function process($objectId,$userId,$newData)
{
$error = '';
if((!$object = $this->getObject($objectId)) && !$object->userOwnsObject($userId))
{
$error = 'Object invalid';
}
// Is it wrong to hate multi-line conditionals?
elseif(!$this->setValidationRules() || (!$parent = $object->getParentObject()) ||
!$parent->prepareForChildUpdate() || !$this->isValid($newData,$parent))
{
$error = 'Data invalid';
}
elseif((!$newData = $this->preProcessData($newData)) || !$object->isWriteable())
{
$error = 'Object not writeable';
}
// Where does doServerIntensiveProcess() with no return value go??
elseif(!$object->write($newData))
{
$error = 'Unable to write to object';
}
else
{
// Success!
$parent->childUpdated();
}
return $error;
}
Я просто не уверен, что лучше всего справиться с такими вложенными функциональными возможностями типа «если это то потом делать, то потом, если это так делать». Спасибо вам за ваше понимание!