4

さまざまなコンテキスト (システム内の API) で使用される場合、オブジェクト メソッドへの何らかのアクセス制御を整理する必要があります。コード例を次に示します。

    class A
    {
      public function doA(){}
      public function doB(){}
    }

    class APIAClient
    {
      public function getA()
      {
        return new A();
      }
    }

    class APIBClient {
      public function getA()
      {
        return new A();
      }
    }

APIAClient では、オブジェクト A に doA() と doB() の両方のメソッドが必要ですが、APIBClient では doB() メソッドは必要ありません。

今のところ、APIBClientAProxy を実装しました (APIBCleint->getA() によって返されます)。

   class APIBClientAProxy
   {
     private $a = new A;
     public function doA()
     {
       $this->a->doA()
     }
   }

しかし、すべてのコンテキスト (つまり API) に追加のプロキシ オブジェクトを使用せずに、私の問題を解決するためのより良いパターンがあるかもしれません。特定のコンテキストで許可されているメソッドのリストを使用して魔法の __call メソッドについて考えていますが、魔法の呼び出しはドキュメントを作成するのが難しく、ドキュメントは私のアプリの大きなポイントです (API は十分にドキュメント化する必要があります)。

ありがとう!

4

3 に答える 3

4

継承の代わりに、トレイト (PHP 5.4 で導入) を介してコンポジションを使用できます。

最初に特徴を定義する

trait A {
  public function doA() {
    // do something here
  }
}

trait B {
  public function doB() {
    // do something here
  }
}

次に、クラス宣言でそれらの特性を使用します

class APIAClient {
  use A, B

}

class APIBClient {
  use A
}
于 2012-12-03T16:00:58.107 に答える
1

次のように、ここで継承を使用できます。

class A {
    public function doA() {
        // do something here
    }
}

class B extends A {
    public function doB() {
        // do something here
    }
}

class APIAClient
{
    public function getObj() {
        return new B();
    }
}

class APIBClient {
    public function getObj() {
        return new A();
    }
}

このように、getObj()APIAClientを呼び出すと、 と のB両方を持つdoA()インスタンスが返されますdoB()。ただし、 on で呼び出すと、のみを持つAPIBClientのインスタンスが返されます。AdoA()

于 2012-12-03T15:50:31.807 に答える
1

インスタンスがいつどのように作成されるかに応じて、クラスを変更することはできません (そうではありません)。
ハックな回避策を使用できます(ただし、お勧めしません)

class A
{
    private $_canDoB = null;
    public function __construct($doB = true)
    {
        $this->_canDoB = !!$doB;//force bool
    }
    public function doB()
    {
        if ($this->_canDoB === false)
        {
            throw new LogicError('You can\'t doB');
        }
    }
}

したがって、偽の値を A (in your APIBClient)のコンストラクターに渡すdoBと、エラーがスローされます。ただし、継承も使用することをお勧めします。

class AB
{
    public function doA()
    {
        //both B and B share this method
    }
}
class B
{//nothing atm
}
class A
{
    public function doB()
}

そして、クラスの新しいインスタンスを返すのAPIAClientに対しnew A()、を返します。タイプヒンティングを使用する場合、インスタンスをチェックするだけです:APIBClientB
AB

public function doSomething(AB $instance)
{
    if ($instance instanceof A)
    {
        return $instance->doB();
    }
    return $instance->doA();
}

または、タイプヒンティングとタイプチェックに依存しない場合は、次のような多くの関数のいずれかをいつでも使用できますmethod_exists

于 2012-12-03T16:05:26.900 に答える