我遇到了一个小问题。这是:
-
这是我的单例抽象类:
abstract class Singleton { protected static $_instance = NULL; /** * Prevent direct object creation */ final private function __construct() { $this->actionBeforeInstantiate(); } /** * Prevent object cloning */ final private function __clone() { } /** * Returns new or existing Singleton instance * @return Singleton */ final public static function getInstance(){ if(null !== static::$_instance){ return static::$_instance; } static::$_instance = new static(); return static::$_instance; } abstract protected function actionBeforeInstantiate(); }
-
之后,我创建了一个抽象注册表类:
abstract class BaseRegistry extends Singleton { //... }
-
现在是会话注册的时候了。
class BaseSessionRegistry extends BaseRegistry { //... protected function actionBeforeInstantiate() { session_start(); } }
-
最后一步:
class AppBaseSessionRegistryTwo extends BaseSessionRegistry { //... } class AppBaseSessionRegistry extends BaseSessionRegistry { //... }
-
测试
$registry = AppBaseSessionRegistry::getInstance(); $registry2 =AppBaseSessionRegistryTwo::getInstance(); echo get_class($registry) . '|' . get_class($registry2) . '<br>';
输出:
AppBaseSessionRegistry|AppBaseSessionRegistry
我的期望是:
AppBaseSessionRegistry|AppBaseSessionRegistryTwo
为什么我会得到这样的结果?我该如何重新制作代码以获得预期的结果?
更新:我在我的框架中使用了这个。用户将扩展我的BaseSessionRegistry
类并添加他们的内容。我想在我的框架类
您需要这样做:
class AppBaseSessionRegistryTwo extends BaseSessionRegistry {
protected static $_instance = NULL;
// ...
}
class AppBaseSessionRegistry extends BaseSessionRegistry {
protected static $_instance = NULL;
//...
}
如果不单独声明静态属性,它们将共享其父级的相同静态属性。
更新:如果您不希望子级声明静态属性,那么您可以将静态属性声明为父级的数组。
abstract class Singleton {
protected static $_instances = array();
// ...
/**
* Returns new or existing Singleton instance
* @return Singleton
*/
final public static function getInstance(){
$class_name = get_called_class();
if(isset(self::$_instances[$class_name])){
return self::$_instances[$class_name];
}
return self::$_instances[$class_name] = new static();
}
abstract protected function actionBeforeInstantiate();
}
您的第一行:
$registry = AppBaseSessionRegistry::getInstance();
将用CCD_ 3实例填充CCD_。在您的下一行$registry2 =AppBaseSessionRegistryTwo::getInstance();
中,受保护的静态$_instance已经有了一个值,该实例将被返回。
一般来说,辛格尔顿和静力学是邪恶的。把它们结合在一起太可怕了。从事良好的OO编程,避免使用Singleton和statics。
$registry = AppBaseSessionRegistry::getInstance();
上面的语句使用类AppBaseSessionRegistry的对象设置$_instance
由于在getInstance方法中,我们正在检查它之前是否已设置,因此返回因此您的第二个报表的值
$registry2 =AppBaseSessionRegistryTwo::getInstance();
getInstance将返回类AppBaseSessionRegistry的对象,即引用同一对象的$registry1和registry2