2009-05-29 7 views
6

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

class Foo { 

function __construct() 
{ 

    $active = false; 

    if(!$active) 
    { 
    return false; 
    } 

} 

} 

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

ответ

7

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

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

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

+1

Я звоню этот класс из другого файла.Если я устанавливаю значение $ active равным false, я бы не хотел, чтобы ни один из методов не запускался, а для другой страницы загружалась нормально. Например, если я положил кубик; в конструкции он будет умирать за каждую страницу, назвавшую этот объект. – 2009-05-29 15:09:25

+0

В этом случае вы можете использовать шаблон фабрики, чтобы возвращать фиктивный объект, если $ active является ложным и «реальным» объектом, если это не так. Это не самое изящное решение, но это прекрасно подойдет. – n3rd

0

Я думаю, что 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; 

    } 
} 
+0

Не работает. Я не думаю, что можно вернуть значение в конструкцию. :/ – 2009-05-29 15:08:18

+0

Это Доза работы. Как вы можете вызвать функцию, такую ​​как if ($ this-> check ($ active)) {do something} – Mantichora

1

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

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

3

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

3

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

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

2

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

Это не объектно-ориентированное программирование:

$o = new myObject(); 
if (!is_object($o)) // then what??? 
Смежные вопросы