Блокирование возможности создания классов непосредственно в обход фабрики

В базовом классе для всех моделей нашей MVC-системы я создал фабричный метод BaseCLass :: getNew (), который возвращает экземпляр запрошенного дочернего класса при вызове через SomeChildClass :: getNew ().

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

new SomeChildClass 

будет генерировать исключение при создании, и будут использоваться только классы, созданные на заводе.

Любые идеи, как это можно достичь?

Наш код написан на PHP, но хороший шанс, что ваша идея будет ценна, даже если вы думаете на другом языке.

edit: Я не могу сделать свой конструктор закрытым, так как конструктор фреймворка в классе, который я наследую, является общедоступным, и php не позволит мне это.

Related of "Блокирование возможности создания классов непосредственно в обход фабрики"

При создании класса есть частный конструктор .

Обновление – решение, которое покрывает ваши заявленные требования

 class Base { private static $constructorToken = null; protected static function getConstructorToken() { if (self::$constructorToken === null) { self::$constructorToken = new stdClass; } return self::$constructorToken; } } class Derived extends Base { public function __construct($token) { if ($token !== parent::getConstructorToken()) { die ("Attempted to construct manually"); } } public static function makeMeOne() { return new Derived(parent::getConstructorToken()); } } 

Это решение использует правила равенства объектов для stdClass , сохраняя объект «волшебный пароль» в базовом классе, к которому могут обращаться только производные классы. Вы можете настроить его на вкус.

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

Сделав защитный конструктор дочернего класса. Родительский класс будет иметь доступ ко всем защищенным методам ребенка. Любая попытка прямого создания дочернего элемента (то есть: new child ) приведет к фатальной ошибке.

 <?php class factory { static public function create() { return new child; } } class child extends factory { protected function __construct() { echo 'Ok'; } } $c = factory::create(); // Ok $c2 = new child; // fatal error ?> 

Хотя этот метод не позволит вам исключать исключение 🙁

Если это абсолютно необходимо, приходит в голову функция debug_backtrace () (помимо использования singleton для самого ребенка или шаблонов пула принудительных объектов, использующих и передающих GUID, сгенерированные фабрикой и проверенные дочерним). Внутри дочернего конструктора посмотрите на значение второго массива, чтобы убедиться, что функция «function» === «create» и «class» === «factory». Исключить исключение, если оно не совпадает. Я не предлагал это изначально, только потому, что я Подозреваемый с использованием debug_backtrace может дать удар производительности.

Объявите конструктор класса private, и его можно вызвать только из собственных методов класса, таких как getNew() .

существует несколько способов его реализации

  • сделать магию для родителей
  • функция волшебства пользователя __autoload; проверьте тип класса и с помощью ошибки с недопустимым сообщением

http://php.net/manual/en/function.is-a.php