Можно ли выйти изящно в конструкторе? - PullRequest
6 голосов
/ 29 мая 2009

Возможно ли изящно выйти из конструктора в php? Что-то с эффектом

class Foo { 

 function __construct()
 {

   $active = false;

   if(!$active)
   {
    return false;
   }

 }

}

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

Ответы [ 6 ]

7 голосов
/ 29 мая 2009

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

class FooFactory {
    function makeFoo() {
        return $someConstraint ? null : new Foo();
    }
}

Может быть, вы можете немного рассказать о том, чего именно вы хотите достичь.

3 голосов
/ 29 мая 2009

Я чувствую запах образца Прокси То, чего вы пытаетесь достичь, это не , когда конструктор терпит неудачу изящно , а , не позволяющий вызывать методы объекта на основе некоторого $ active критерия .

Это может указывать вам в правильном направлении. Или, может быть, нет (= >> Мне не очень нравится страница, на которую я ссылался, но это было лучшее, что я мог найти для PHP). Дайте Прокси прочитать, возможно, из других источников. По сути, ваш ProxyObject будет иметь ссылку на real объект, который будет выполнять методы . Ваш клиентский код будет вызывать методы для ProxyObject, как если бы это была реальная вещь , и ProxyObject будет решать, активен он или нет, передавать ли сообщение реальной вещи или ничего не возвращать или нули или фиктивные значения. Звучит хорошо?

3 голосов
/ 29 мая 2009

Заставь его взорваться. В конструкторе не бывает грациозного сбоя. Возможно в вызывающем коде, но не в конструкторе. Брось исключение и обработай его соответствующим образом.

2 голосов
/ 29 мая 2009

Если конструктор выполняет так много логики, значит, он плохо спроектирован. Оставьте его пустым, передайте ему конфигурацию с помощью метода установки и оставьте его там неудачным.

Это не ОО программирование:

$o = new myObject();
if (!is_object($o)) // then what???
1 голос
/ 29 мая 2009

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

Причина этого в том, что исключение вынуждает программу работать с ним и выдает неверные данные. Если вы вернете значение, скажем, -1 или что-то еще, программа может продолжать молча и игнорировать это, пока это не вызовет проблему позже в будущем. Создание исключения не позволяет этим тихим ошибкам войти в код. Возможно, вы знаете, что он возвращает false, если он не сработал должным образом, но ваш коллега не может и может с радостью попытаться использовать объект, который, по его мнению, был создан им, чтобы выяснить, что это действительно логическое значение.

0 голосов
/ 29 мая 2009

Я думаю, что N3rd предложил очень крутое решение, но вот еще один более простой метод.

class Foo {

    private $active = TRUE;

    function __construct() {

        $this->check ( $active ); 

            //OR
            //if ($this->check ( $active )) { do something } 
    }

    function check($var) {
        if (! $var) {
            $this->active = FALSE;
            return FALSE;
        }
        return TRUE;

    }
}
...