后期静态绑定

时间:2012-09-08 10:16:01

标签: php oop design-patterns

我有一点问题。这是:

  1. 这是我的单身抽象类:

    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();
    
    }
    
  2. 之后我创建了一个抽象的注册表类:

    abstract class BaseRegistry extends Singleton
    {
        //...
    }
    
  3. 现在是会议注册的时候了。

    class BaseSessionRegistry extends BaseRegistry
    {
    
    //...
    
    protected function actionBeforeInstantiate()
    {
        session_start();
    }
    
    }
    
  4. 最后一步:

    class AppBaseSessionRegistryTwo extends BaseSessionRegistry { //... }
    
    class AppBaseSessionRegistry extends BaseSessionRegistry { //... }
    
  5. 测试

    $registry = AppBaseSessionRegistry::getInstance();
    $registry2 =AppBaseSessionRegistryTwo::getInstance();
    
    echo get_class($registry) . '|' . get_class($registry2) . '<br>';
    
  6. 输出:

    AppBaseSessionRegistry|AppBaseSessionRegistry
    

    我的期望是:

    AppBaseSessionRegistry|AppBaseSessionRegistryTwo
    

    为什么我得到这样的结果? 我怎样才能重新制作代码以获得我期望的结果?

    更新:我在我的框架中使用它。用户将扩展我的BaseSessionRegistry课程并添加他们的内容。我想在我的框架类

    中解决这个问题

3 个答案:

答案 0 :(得分:4)

你需要这样做:

class AppBaseSessionRegistryTwo extends BaseSessionRegistry {
    protected static $_instance = NULL;
    // ...
}

class AppBaseSessionRegistry extends BaseSessionRegistry { 
    protected static $_instance = NULL;
    //... 
}

如果您没有单独声明静态属性,它们将共享其父级的静态属性。

更新 的 如果您不希望子类声明静态属性,则可以将static属性声明为父类的数组。

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();

}

答案 1 :(得分:1)

你的第一行:

$registry = AppBaseSessionRegistry::getInstance();

将使用protected static $_instance实例填充AppBaseSessionRegistry。在您的下一行$registry2 =AppBaseSessionRegistryTwo::getInstance();上,受保护的静态$ _instance已经有一个值,并且将返回该实例。

一般来说,单身人士和静电是邪恶的。结合它们是可怕的。从事良好的OO编程业务,避免单身人士和静态。

答案 2 :(得分:1)

 $registry = AppBaseSessionRegistry::getInstance();

以上语句使用AppBaseSessionRegistry类的对象设置$ _instance 因为在getInstance方法中,我们检查它是否先前已设置然后返回 因此,你的第二个陈述的价值

$registry2 =AppBaseSessionRegistryTwo::getInstance();

getInstance将返回类AppBaseSessionRegistry的对象,即$ registry1和注册表2引用相同的对象