我有一个Factory Method
来实例化一个类。有没有办法防止这个类直接实例化?
我看到的唯一选择是使用传递给__construct()
的参数,但这不是我正在寻找的东西。
另一方面,将__construct()
设为私有是理想的,但我不希望MyClass
在没有实际需要的情况下延长Factory
。
你们有什么想法?
工厂方法:
class Factory
{
public static function instance()
{
return new MyClass(true);
}
}
MyClass的:
class MyClass
{
public function __construct($isFactory = false)
{
if (!$isFactory) {
throw new Exception('Use Factory::instance() to create an object');
}
}
}
答案 0 :(得分:2)
有一些黑客可以做到这一点:
protected
构造函数我没有宣传任何相关内容。我个人所做的是使用@internal
之类的东西来记录API,并在合同之后将其留给客户。
答案 1 :(得分:1)
从本质上讲,您的代码应该是这样的:
工厂
<?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
答案 2 :(得分:0)
最简单的方法是将基类定义为abstract
。 abstract
类不能直接实例化,因此您必须在继承的类中重新定义其抽象成员:
abstract class Factory
{
abstract public function foo();
}
class InheritedClass extends Factory
{
public function foo()
{
// Do something
}
}
// $obj1 = new Factory(); // Will produce an error
$obj1 = new InheritedClass(); // Will be executed successfully
您可以在PHP: Class Abstraction - Manual的abstract
类中阅读更多内容。