1

私は、中央のクラスによってすべてまとめられたかなりの数のクラスがあるライブラリに取り組んでいます。この中央クラスは、セットアップ/構成の目的で、他のクラスの特定のメソッドを呼び出す必要があります。これらのメソッドは、中央クラスが呼び出すことができるようにパブリックである必要がありますが、ユーザーにこれらのメソッドを呼び出させたくありません(望ましくない動作を引き起こす可能性があるため)。

私の友人が行った提案の1つは、パラメーターを使用してコンストラクターを使用し、構築時にセットアップを実行できるようにすることでした。このライブラリの目的では、それは簡単には不可能です。問題のクラスは拡張することを目的としており、ユーザーが独自のコンストラクターを持ちたい場合は、コンストラクターパラメーターに奇妙な要件を課したくありませんでした。さらに複雑なのは、構成に使用される情報の一部がユーザーに利用できないことです。ユーザーが利用できるようにし、構築中に適切なクラスにルーティングすることを信頼する必要があります。

現在、私の解決策は、これらのメソッドに何かをプレフィックスとして付け、そのプレフィックスを付けてメソッドを呼び出さないようにユーザーに注意することです。これは、より制限されたメソッドを追加できるほど「柔軟」ですが、それでもユーザーが私の指示に従うことを前提としています。また、これは最も洗練されたソリューションではありません。

これらの方法を簡単に制限する方法があるのではないかと思いました。それらを呼び出す中央クラスであるかどうかをチェックする行をそれらに追加することを考えましたが、それも最善の解決策ではないようです。

編集:このアーキテクチャの目的を説明する必要があります。クラスはそれぞれ、一連の操作で特定のタスクを実行します。中央クラスの仕事は、1つのクラスにそのタスクを実行し、結果を収集し、結果を必要とする他のクラスに分散するように命令することです。次に、クラスは次のクラスに移動し、同じことを行います。タスクの実行方法は、拡張クラス次第です。私が制限したい方法は、結果の分散を助ける方法です。それが私の意図をより明確にすることを願っています。

4

1 に答える 1

1

それはすべてあなたの中央クラスの役割に依存します。あなたの説明から、それはある種のスプーラーまたはスケジューラーのようです。スプールオブジェクトが実際にその中央クラスによって作成されている場合は、それらのオブジェクトをプライベートにすることでクライアントからオブジェクトを非表示にし、中央オブジェクトにスタブを作成して、クライアントが許可した関数を呼び出せるようにすることができます。

例(概念的なコード、実際にはコンパイルされない場合があります)

class HiddenSubClass {
  public function MyFunc() {
    echo "hello";
  }
}

class CentralClass {
  private $obj;

  function __construct() {
     $obj=new HiddenSubClass();
  }

  function SubClassMyFunc () {
    $obj->MyFunc();
  }
}

クライアントにはCentralClassオブジェクトしかないため、SubClassMyFuncのみを呼び出すことができ、MyFuncは呼び出すことができません。これの欠点は、ライブラリのオブジェクト指向構造もクライアントから隠すことです。これは、望ましい場合と望ましくない場合があります。

ただし、オブジェクトがクライアントによって作成されてから中央クラスに渡される場合、オブジェクトの所有者(クライアント)が必要な操作を実行できないようにするためにできることはほとんどありません。クライアントは、セントラルクラスができることなら何でも呼び出すことができます。次に、保護するコードを上記のクラスから「ヘルパークラス」または中央クラス自体に移動する必要がある場合があります。

編集:もしあなたがそれを「ハック」したいのなら、これは一つのアプローチでしょう(それはかなり臭いので、私はそれをお勧めしませんが):

あなたの中央クラスに「プライベートシークレット」を持ってください。

class CentralClass {
  private $MySecret=42;

  function IsValidSecret($anumber) {
    return ($anumber==$this->MySecret);   
  } 
}

これで、中央クラスは、スプールされたオブジェクトで特定の「保護された」関数を呼び出すときに、パラメーターとして$MySecretを渡すことができます。CentralClassがシングルトンの場合、スプールオブジェクトはそのシングルトンを呼び出して、渡されたシークレットが正しいかどうかを確認できます。CentralClassがシングルトンでない場合は、そのオブジェクトも渡す必要があります。

class MySpooledObject {
  function SuperSecretFunction ($asecret) {
    if (!$CentralSingleton->isValidSecret($asecret)) { die(); }
  }

  function SuperSecretFunction2 ($acentralobject,$asecret) {
    if (!$acentralobject->isValidSecret($asecret)) { die(); }
  }
}

これには多くのバリエーションがあります。中央クラスは、オブジェクトのメソッドを呼び出す前に内部フラグを設定し、オブジェクトが戻ったときにそれをリセットできます。このシナリオでは、オブジェクトは中央クラスにそのフラグが設定されているかどうかを尋ねることができ、シークレットを渡す必要はありません。ただし、シングルトンでない限り、$acentralobjectが必要です。

于 2013-02-23T18:09:08.700 に答える