2016-07-25 19 views
1

この問題を解決するにはどうすればよいですか?多分これのためにどんなパターンが作られたでしょうか?PHP OOP内部メソッド呼び出し

私はクラスMasterを持っています。これはDIを通してSlaveオブジェクトを管理します。クラスSlaveのインスタンスは、親のMasterを内部に持つ必要があります。このような何か:

class Master 
{ 
    private $slave; 

    public function __construct(Slave $slave) 
    { 
    $slave->registerMaster($this); 
    $this->slave = $slave; 
    } 
} 

class Slave 
{ 
    private $master; 

    public function registerMaster(Master $master) 
    { 
    $this->master = $master; 
    } 
} 

のみクラスMasterregisterMasterメソッドを呼び出すことができます。この例で私を助けてくれるパターンはありますか?

+0

you'rは何ですか今問題? – jmattheis

+0

私はユーザー自身がこれを行うことができないためにregisterMasterを外部に無効にしたいと思います。それをクリーンアップし、それを適切に定義してください - – Mati

+0

あなたの質問は意味をなさないdoes't。私が見ているすべてはあなたが唯一の '' registerMaster() 'を呼び出す機能をMaster'できるようにしたいということでしょうか? – Darren

答えて

2

register Masterメソッドのみを呼び出すことができます。この例で私を助けてくれるパターンはありますか?

PHPではフレンドクラスの概念がないため、パブリックメソッドを別のクラスから隠す方法はありません。マスターとスレーブは今、同じ基本クラスを拡張するので、あなたが相続し、保護された可視性

abstract class LinkedEntity { 
    protected $master; 
    protected $slave;  
} 

class Master extends LinkedEntity { 
    public function __construct(Slave $slave) { 
     $this->slave = $slave; 
     $this->slave->master = $this; 
    } 
} 

class Slave extends LinkedEntity {} 

$slave = new Slave; 
$master = new Master($slave); 

を使用することができます

、保護されたプロパティは、彼らにはなく、他のクラスにアクセスできます。 LinkedEntityクラスで定義されている保護されたメソッドについても同様です。したがって、protected registerMaster(Master $master)メソッドを配置して、プロパティを直接割り当てる代わりにそのメソッドを実行できます。

個人的に、私はとてもきれいではないことを見つけて、私はむしろ、例えば、あなたが本当にここ双方向の関連付けを必要とするか、それが一方通行の関連性を持っているのに十分良いのかどうかかどうかを確認したいですマスターからスレーブへのみ、またはその逆に

別、さらに悪いオプションは、コールスタックを検査するために、次のようになります。

class Slave { 
    private $master; 
    public function registerMaster(Master $master) 
    { 
     if (debug_backtrace(null, 2)[1]["class"] === Master::class) { 
      throw new RuntimeException("Only Masters may call Slaves"); 
     } 
     $this->master = $master; 
    } 
} 

方法をチェックし、前のクラスであれば、コールスタック内の(自分のregisterMasterに電話をした1が実際のマスターでした。あなたのメソッドが呼び出される側が誰の情報に依存する場合しかし、それは通常は悪いデザインの兆候だ。

第三の選択肢は、例えば

、リフレクション経由してスレーブのメソッドの可視性を突破するだろう
class Master { 
    private $slave; 
    public function __construct(Slave $slave) { 
     $this->slave = $slave; 
     $fn = new ReflectionMethod($slave, 'registerMaster'); 
     $fn->setAccessible(true); 
     $fn->invoke($slave, $this); 
    } 
} 

class Slave { 
    private $master; 
    private function registerMaster(Master $master) 
    { 
     $this->master = $master; 
    } 
} 

また、これは最適ではありません。なぜなら、OOPのコア原則は情報隠蔽であり、ここではそれを壊しているからです。私たちは指定された私的な可視性を突破し、それをマスターのために一般に公開しています。また、他のオブジェクトが同じことをするのを妨げることはありません。

0

クラスの追加メソッドを回避する別の方法は、別のクラスのプライベートスコープに閉鎖をバインドすることですので、あなたが直接、すべてのメソッドとプロパティにアクセスすることができるようになります:

class Master 
{ 
    private $slave; 

    public function __construct(Slave $slave) 
    { 
    $this->slave = $slave; 
    $master  = $this; 
    $masterInjector = function (Master $master) { 
     $this->master = $master; 
    }; 
    $masterInjector->call($slave, $master); 
    } 
} 

class Slave 
{ 
    private $master; 
} 
関連する問題