2014-12-13 2 views

ответ

4
class C 
{ 
    protected function __construct() 
    { 
    } 

    public static function getObject() 
    { 
     return new self(); 
    } 
} 

UPDATE:

Код выше выполняет требование: класс не может быть создан с помощью new, нужно использовать фабричный метод getObject() для создания объекта. Однако ОП не указала причину, по которой им нужна такая конструкция.

Существует несколько причин возникновения такой конструкции; одним из них является создание объектов типа C с некоторой инициализацией, которая по какой-либо причине не может быть выполнена в конструкторе класса.

Другой причиной такого способа строительства объектов класса C является шаблон проектирования Singleton; который на самом деле является «анти-шаблоном», но это еще одна дискуссия; в целях реализации Singleton, класс C должен выглядеть следующим образом:

class C  
    { 
     private static $instance = NULL; 

     protected function __construct() 
     { 
     } 

     public static function getObject() 
     { 
      if (! isset(self::$instance)) { 
       self::$instance = new self(); 
      } 
      return self::$instance; 
     } 
    } 

Singleton или нет, потому что метод getObject() статична он не может быть погасил или осмеянным рамки испытаний и ее первоначальной реализации должны быть использованы. Более того, поскольку это единственный способ создать объекты класса C, другие классы, которые используют этот класс, не могут быть протестированы изолированно.

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

Если создание объектов класса C должно выполняться определенным способом из-за его сложной инициализации, лучшим способом является использование шаблона проектирования Builder. Сделайте его нестационарным методом другого класса («строитель») и попросите программистов (используя документацию по классу) не создавать объекты класса C напрямую, используя new. Таким образом, это не влияет на тестируемость других классов.

+0

Обратите внимание, что это возвращает новый объект 'C' при каждом вызове' getObject() ', который может быть не предназначен для всех читателей. –

+1

В вопросе нет ограничений на одноэлементное ограничение.Он просто говорит, чтобы запретить создание с использованием 'new' и обеспечить использование фабричного метода. – axiac

+0

Конечно. Я признаю, что дьявол в деталях. Моя забота о будущих читателях, так как этот вопрос, казалось бы, прост, является скользким склоном. –

3

Я хочу, чтобы отключить класс быть instantized от new оператора

Общий подход приватизировать конструктор.

class Example { 
    private function __construct() { 
    } 
} 

Следующие могут привести к фатальной ошибке.

$object = new Example(); 

В то время как это будет работать, я призываю вас, и будущие читатели, обзор Design Patterns in PHP.

+0

В вашем ответе отсутствует заводской метод. Я понимаю, что @ aciac отвечает 'getObject' –

+0

@Paul Sasik. Мой ответ намеренно касается только первой части вопроса, чтобы побудить будущих читателей больше узнать о последствиях этого шаблона. –

Смежные вопросы