у меня есть Factory Method
чтобы экземпляр класса. Есть ли способ предотвратить прямое создание экземпляров этого класса?
Единственный вариант, который я вижу, это использовать аргумент, переданный в __construct()
, но это не то, что я ищу.
С другой стороны, делая __construct()
личное было бы идеально, но я не хочу MyClass
продлить Factory
без фактической необходимости.
Что, вы парни, думаете?
Заводской метод:
class Factory
{
public static function instance()
{
return new MyClass(true);
}
}
Мои занятия:
class MyClass
{
public function __construct($isFactory = false)
{
if (!$isFactory) {
throw new Exception('Use Factory::instance() to create an object');
}
}
}
Для этого есть хаки:
protected
конструкторЯ не продвигаю ничего из этого. Что я лично делаю, так это документирую API с такими вещами, как @internal
и оставьте это клиенту после того контракта.
По сути, ваш код должен был прочитать что-то вроде этого:
ФАБРИКА
<?php
class Factory {
public static function instance(){
return new MyClass(true); //HERE YOU ARE INSTANTIATING
}
}
КЛАСС, КОТОРЫЙ БУДЕТ ИНСТАНЦИРОВАНО С ЗАВОДА
<?php
//NOT MyClass() <--- YOU ARE DEFINING.... NOT INSTANTIATING...
class MyClass {
public function __construct($isFactory = false) {
if (!$isFactory) {
throw new Exception('Use Factory::instance() to create an object');
}
}
//...MORE METHODS
}
Не могли бы вы попробовать это вместо этого?
<?php
class Factory
{
private static $FACTORY_GUARANTOR; //ONLY SET DURING INSTANTIATION
public static function instance($type) {
if (class_exists($type)) {
self::$FACTORY_GUARANTOR = 1;
$instance = new $type();
self::$FACTORY_GUARANTOR = null;
return $instance;
}
else {
throw new Exception("Class not found...");
}
}
//YOU CAN GET $FACTORYGUARANTOR EXTERNALLY BUT NEVER SET IT;
public static function getGuarantor(){
return self::$FACTORY_GUARANTOR;
}
}class MyClass {
protected $property1;
protected $property3;
protected $property2;
public function __construct() {
// IF SOMEONE TRIES TO INSTANTIATE THE CLASS OUTSIDE OF THE FACTORY... BLOW A WHISTLE
if(!Factory::getGuarantor()){
throw new Exception('Use Factory::instance() to create an object');
}
// IF THE PROGRAM MADE IT TO THIS POINT;
// JUST INSTANTIATE THE CLASS BECAUSE MOST LIKELY IT IS COMING FROM THE FACTORY
var_dump($this); // A LITTLE CONFIRMATION....
}
//...MORE METHODS
}
// TRY IT OUT:
/*INSTANCE A: RIGHT*/ $theClass = Factory::instance("MyClass"); //INSTANTIATES THE CLASS
/*INSTANCE B: WRONG*/ $theClass = new MyClass(); //THROWS AN EXCEPTION