2009-06-29 9 views
7

から子クラスをインスタンス化:私はそれで工場出荷時のパターンの機能を持つクラスを持つ親クラス(PHP)

abstract class ParentObj { 
    public function __construct(){ ... } 
    public static function factory(){ 
     //returns new instance 
    } 
} 

私は子供たちが工場出荷時の関数を呼び出すと、呼び出し元のインスタンスを返すことができるようにする必要がありますクラス:$child = Child::factory();であり、好ましくは子クラスのファクトリ関数をオーバーライドしないでください。

私はこれを無駄にするための複数の異なる方法を試しました。 __CLASS__のように、反射を使用するソリューションから離れることを好むでしょう。

(それが重要ならば、私はPHP 5.2.5を使用しています)

答えて

10

あなたは、PHP 5.3(released 30-Jun-2009)にアップグレードすることができた場合は、ソリューションを提供する可能性がある、late static bindingをチェックアウト:私は

abstract class ParentObj { 
    public function __construct(){} 
    public static function factory(){ 

     //use php5.3 late static binding features: 
     $class=get_called_class(); 
     return new $class; 
    } 
} 


class ChildObj extends ParentObj{ 

    function foo(){ 
     echo "Hello world\n"; 
    } 

} 


$child=ChildObj::factory(); 
$child->foo(); 
+0

... –

+0

LSBようです私が自分で見つけることができる最高のソリューションになるようにしてください。 私がアップグレードするまでは、子の名前をfactory()に渡すか、名前をプロパティとして定義してfactory()から取得してください。 –

+0

PHPマニュアルによれば、 get_called_class() 'は' __CLASS__'のように動作しますhttp://us.php.net/manual/en/function.get-called-class.php –

0

を謙虚な意見あなたがしようとしていることは意味をなさない。

工場出荷時のパターンは次のように動作します:誰もが、その間にステップアップしない場合、私はすぐにいくつかのコードを試してみますので、私は分でRC4と遊んだ

abstract class Human {} 

class Child extends Human {} 
class Fool extends Human {} 

class HumanFactory 
{ 
    public static function get($token) 
    { 
     switch ($token) 
     { 
      case 'Kid' : return new Child(); 
      case 'King': return new Fool(); 
      default : throw new Exception('Not supported'); 
     } 
    } 
} 

$child = HumanFactory::get('Kid'); 
+0

これは完全な工場パターンです。私は単純に 'new'演算子をバイパスし、子クラスに読みやすさと連鎖を提供する静的メソッドを意味しました。 –

+0

なぜ新しい演算子をバイパスしたいですか? –

+1

あなたの例を使用するには、新しいChild() - > foo()は機能しません。 (私が使っているように) "factory"メソッドを追加することで、Child :: factory() - > foo() - > bar()のようにいくつかの行を分割するより読みやすい(IMHO)ことができます。 私はそれが問題だと思うし、公正であるためには、あなたの工場の実装は有用なものです。ちょうど私が探しているもののためではありません。 –

関連する問題