Переключение методов для одного результата - PullRequest
1 голос
/ 17 февраля 2009

У меня есть ситуация, когда мне нужно обращаться к разным объектам в PHP разными способами, чтобы найти некоторые данные.

Вопрос касается скорее форматирования кода, чем реальной проблемы программирования. Я пытаюсь не использовать несколько if для сбора таких данных, как:

$data = obj->getData();
if (!isset($data)) $data = othObj->getThisData();
if (!isset($data)) $data = anothObj->getTheData();
if (!isset($data)) $data = anothOne->getAData();
...
process($data)

Мне было интересно, каковы лучшие практики в этом случае, если есть лучший способ использования других процедур, таких как foreach или switch/case.

Спасибо!

Ответы [ 5 ]

2 голосов
/ 17 февраля 2009

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

$dataCallback = array(
    array($othObj, 'getData'),
    array($othObj, 'getThisData'),
    array($anothObj, 'getTheData'),
    array($anothOne, 'getAData'),
);

for($i = 0, $t = count($dataCallback); !isset($data) && $i < $t; $i++) {
  $callback = $dataCallback[$i];
  $data = call_user_func($callback);
}

if (isset($data))
  process($data);
else
  //no valid data returned at all ...
0 голосов
/ 21 февраля 2009

Я бы, вероятно, сгруппировал объекты для запроса данных в массив:

$objArray = array($obj, $othObj, $anothObj, ... );

Затем выполните цикл while, пока у меня не появятся данные:

$i = 0;
do {
   $data = $objArray[$i]->getData();
   $i++;
} while(!isset($data) && $i < count($objArray));
0 голосов
/ 17 февраля 2009
($data = $ob1->get()) || ($data = $ob2->get()) || ($data = $ob3->get());

Работало бы, но если вы получили функцию, возвращающую пустой массив или ложную или пустую строку вместо NULL, она продолжит поиск данных ...

0 голосов
/ 17 февраля 2009

Лично я бы сделал что-то вроде этого:

$data = null;

if (isset($obj->getData()) $data = $obj->getData();
else if (isset($othObj->getThisData()) $data = $othObj->getThisData();
else if (isset($anothObj->getTheData()) $data = $anothObj->getTheData();
else if (isset($anothOne->getAData()) $data = $anothOne->getAData();

process($data)

Это экономит время обработки, если более ранние объекты действительно что-то возвращают. Так как это настройка elseif, когда он найдет данные, он прекратит обработку других предложений if.

Я не думаю, что в этом случае уместно использовать оператор switch. Переключатели обычно проверяют значение одной переменной ($ a = 1, 2, 3 или 4).

0 голосов
/ 17 февраля 2009
  1. Не выглядит так плохо, как есть.
  2. Было бы немного эффективнее, если бы if были вложенными. например,

     if (!isset($data = othObj->getData()))
     if (!isset($data = othObj->getThisData()))
     if (!isset($data = anothObj->getTheData()))
     $data = anothOne->getAData()))
     // ...
     process($data)
    

    Поскольку вызовов isset меньше (хотя в любом случае они довольно дешевы, я бы об этом не беспокоился).

...