7

少し問題があります。ここにあります:

  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>';
    

出力:

AppBaseSessionRegistry|AppBaseSessionRegistry

私の期待は:

AppBaseSessionRegistry|AppBaseSessionRegistryTwo

なぜ私はそのような結果を得たのですか?そして、どうすればコードを作り直して、期待した結果を得ることができますか?

更新:フレームワークでこれを使用します。そして、ユーザーは私のBaseSessionRegistryクラスを拡張し、自分のものを追加します。フレームワーククラス内でこれを解決したい

4

3 に答える 3

4

これを行う必要があります:

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

}
于 2012-09-08T10:27:09.513 に答える
1

あなたの最初の行:

$registry = AppBaseSessionRegistry::getInstance();

protected static $_instanceAppBaseSessionRegistryインスタンスで埋めます。次の行$registry2 =AppBaseSessionRegistryTwo::getInstance();では、保護された静的$ _instanceにすでに値があり、そのインスタンスが返されます。

一般的に言って、シングルトンと静力学は悪です。それらを組み合わせるのは恐ろしいことです。優れたオブジェクト指向プログラミングのビジネスに参入し、シングルトンとスタティックを避けてください。

于 2012-09-08T10:30:08.580 に答える
1
 $registry = AppBaseSessionRegistry::getInstance();

上記のステートメントは、クラスAppBaseSessionRegistryのオブジェクトで$ _instanceを設定します。
これは、getInstanceメソッドで、以前に設定されているかどうかを確認し、その値を2番目のステートメントに返すためです。

$registry2 =AppBaseSessionRegistryTwo::getInstance();

getInstanceは、クラスAppBaseSessionRegistryのオブジェクト、つまり、同じオブジェクトを参照する$registry1とレジストリ2を返します。

于 2012-09-08T10:44:16.333 に答える