5

MVCシステムのすべてのモデルの基本クラスで、SomeChildClass :: getNew()を介して呼び出されたときに、要求された子クラスのインスタンスを返すファクトリメソッドBaseCLass :: getNew()を作成しました。

今、私はプログラマーにこのファクトリを使用させる方法を探しています。つまり、通常、次のように、クラスを直接作成する必要があります。

 new SomeChildClass

作成時に例外がスローされ、ファクトリによって作成されたクラスのみが使用可能になります。

これをどのように達成できるかについてのアイデアはありますか?

私たちのコードはPHPで書かれていますが、別の言語で考えても、あなたのアイデアが価値のあるものになる可能性は十分にあります。

編集:私が継承するクラスのフレームワークコンストラクターはパブリックであり、phpはこれを許可しないため、コンストラクターをプライベートにすることはできません。

4

4 に答える 4

2

子クラスのコンストラクターを作成するprotected。親クラスは、子の保護されたすべてのメソッドにアクセスできます。子を直接作成しようとすると(つまりnew child、:)、致命的なエラーが発生します。

<?php

class factory
{

    static public function create()
    {
        return new child;
    }

}

class child extends factory
{

    protected function __construct()
    {
        echo 'Ok';
    }

}

$c = factory::create(); // Ok
$c2 = new child; // fatal error

?>

このメソッドでは代わりに例外をスローすることはできませんが:(

その場合、どうしても必要な場合は、debug_backtrace()関数のみが思い浮かびます(子自体にシングルトンを使用するか、ファクトリによって生成され、子によって検証されたGUIDを使用して渡すオブジェクトプールパターンを強制する以外)。子コンストラクター内で、2番目の配列値を調べて、「function」==="create"および"class" ==="factoryであることを確認します。一致しない場合は例外をスローします。最初はこれを提案しませんでした。使用debug_backtraceするとパフォーマンスが低下する可能性があります。

于 2011-03-27T03:15:04.400 に答える
1

クラスにプライベートコンストラクターを持たせることによって。

更新-指定された要件をカバーするソリューション

class Base {
    private static $constructorToken = null;

    protected static function getConstructorToken() {
        if (self::$constructorToken === null) {
            self::$constructorToken = new stdClass;
        }

        return self::$constructorToken;
    }
}

class Derived extends Base {
    public function __construct($token) {
        if ($token !== parent::getConstructorToken()) {
            die ("Attempted to construct manually");
        }
    }

    public static function makeMeOne() {
        return new Derived(parent::getConstructorToken());
    }
}

stdClassこのソリューションは、派生クラスのみがアクセスできる基本クラスに「マジックパスワード」オブジェクトを格納することにより、オブジェクトの同等性ルールを利用します。あなたはそれを味わうために微調整することができます。

私はそれをその考えのように恐ろしいdebug_backtraceとは言いませんが、それでも私は物事が異なって行われるべきであるという印象を持っています。

于 2011-03-27T02:35:04.637 に答える
0

それを実装する方法はいくつかあります

  • 親クラスを私的使用魔法にする
  • ユーザーマジック関数__autoload; クラスのタイプを確認し、許可されていないメッセージのエラーを介して

http://php.net/manual/en/function.is-a.php

于 2011-03-27T03:02:09.570 に答える
0

クラスのコンストラクターをprivateと宣言します。これは、のようなクラス独自のメソッド内からのみ呼び出すことができますgetNew()

于 2011-03-27T02:34:37.780 に答える