2017-01-31 6 views
1

私が取り組んでいるプロジェクトでは、システムのどこでも利用可能なイベントマネージャー(読み取り専用)構成マネージャーとプラグインマネージャーを含むいくつかのオブジェクトが必要です。オブジェクトをPHPのどこでも利用できるようにするには、どのような方法が適していますか?

誰か(C++のバックグラウンドを持つ人)が「グローバル変数が必要な場合はおそらく何か間違っている」と親切に指摘するまで、グローバル変数を使っていました。
彼は、それを必要とするすべての関数に渡される状態オブジェクトの使用を提案しました。
だから私がやった:私はより多くのステートフルな言語で、この方法の利点を見ることができますが

$state = new State(); 
$state->register('eventManager' , new EventManager()); 
$state->register('configManager', new ConfigManager()); 
$state->register('cacheManager' , new CacheManager()); 
$state->register('pluginManager', new PluginManager()); 

$state->get('pluginManager')->initialize($state); 

、それは状態が失われたPHPのような(?主に)ステートレス言語で種類の無意味な私には思えますページが読み込まれた後。

状態オブジェクトをPHPなどの(ほとんどが)ステートレスな言語で渡すことに利点はありますか?それは他のアプローチ(つまりグローバルベースのシステム)よりも利点があり、これを処理する良い方法がありますか?これを行うには

+0

多くの良い質問は、専門家の経験に基づいてある程度の意見を生成しますが、この質問に対する回答は、事実、参考文献、または特定の専門知識ではなく、概ね意見に基づいている傾向があります。一般的な問題を解決するための開発フォーラム(おそらく[quora](http://www.quora.com/Computer-Programming)?)を探したいかもしれません。次に、特定のコーディング上の問題がある場合は、StackOverflowに戻ってください。お手伝いします。 –

+2

あなたがしたいのは* dependency injection *です。ここでのあなたの "state object"は、依存性注入コンテナの最初のスタブのようなものです。ここに何かが状態を持っているかどうかにかかわらず、それはすべて*管理コード関係*です。それはあらゆる言語で有用です。 – deceze

+2

また、PHPは「ステートレス」ではありません。これは、ステートレスな要求を処理するためにWebサーバーで最もよく使用されます。代わりに非常に「ステートフル」な方法で簡単に使用することができます。 – deceze

答えて

2

提案するレジストリは、引き続きグローバル変数です。グローバル変数にアクセスしたい場合(グローバル変数でもオブジェクトであっても)、何か間違ったことをしています。

適切なアプリケーションは、グローバル状態が役割を果たすフェーズのみを持っています。ブートストラップするとき。スクリプトを開始するリクエストはグローバルであり、それと共に送信されるリクエストデータはすべてグローバルであり、アプリケーションに影響を及ぼしファイルやその他の適切なストレージに格納される設定はすべてグローバルです。

最初のフェーズでは、アプリケーションを構成するすべての部分をまとめた依存関係注入を初期化する必要があります。そのオブジェクトグラフは、要求の処理が要求に応答するためにコードのどの部分を呼び出さなければならないかを決定したときに必要に応じて作成される。

通常、この決定は要求を処理するフレームワーク内で行われ、依存性注入はフレームワークを介して行われる可能性もあります。あなた自身のコードは、操作に必要な値だけでなく、必要な他のオブジェクトも受け入れます。

たとえば、コードにデータベースが必要な場合は、データベースオブジェクトのURLと資格情報を受け入れるようにデータベースオブジェクトを構成し、そのデータベースオブジェクトを受け入れるようにリーダーオブジェクトを構成します。

依存性注入のタスクは、単一のデータベースオブジェクトを1つだけ作成するか、複数のものを作成することです。あなたには、多くの欠点があるため、旧式の "シングルトン反パターン"を使う必要はありません。

このシナリオでは、一度作成され、必要なときに注入される依存性注入部分に存在するオブジェクトがいくつかあります。これらのオブジェクトは一度しか作成されないように強制され、グローバルにアクセス可能な変数内には格納されません。しかし、何かがグローバル変数になければなりませんが、これはメインフレームワークオブジェクトとおそらく依存性注入コンテナだけであり、残りのコードとグローバル変数として共有されることはありません。

+0

この場合、これがフレームワークになります。コードからはあまり明確ではありませんが、グローバル変数atmとして$ stateにアクセスするのではなく、最後の行のようにパラメータとして渡しています。 私は依存性注入について少し読んで、それは私が特定の関数のための多くのパラメータで終わると思いませんか?私。依存関係を持つ他の関数を呼び出す関数は、それらの依存関係も同様に取得します。非常に厄介なことはありませんか? – SharkWipf

+1

@SharkWipf - それは非常にうまくできます。あなたの質問には1つの解決策はありません - 特定のクラスにはシングルトンのような単純なソリューションしか必要としないことがあります。他の時代には、Svenの提案のような解決策がより適切です。今日のフレームワークのほとんどは、ブートするための独自の言い回しや意見セットとともに、この正確なことを行う方法の独自の「味」を提供します。 –

+0

これは私が使用し終わったものに最も近く、新しい回答が来ていないように思われるので、これを受け入れたものとしてマークしてください。 – SharkWipf

2

一つの方法は、シングルトンである:

class ConfigManager { 
    private static $instance = NULL; 

    public static function getInstance(){ 
     if(self::$instance === NULL) { 
      self::$instance = new ConfigManager(); 
     } 

     return self::$instance; 
    } 

    private function __construct(){ 
     // Notice that this is private - only getInstance() can call this. 
    } 
} 

// When you need it: 
$config = ConfigManager::getInstance(); 

あり、あなたが求めているものを行う方法についてのさまざまな意見がある - と、私は自分自身がシングルトンが常にあるとは思いませんこれを行う最善の方法です。それは実際にあなたのユースケースに依存します。

つまり、シングルトンは、インスタンスがどこからでもアクセスできるはずのクラスのためのただ1つの共通パターンです。

+0

本当ですか?シングルトン?それらには2つの意見しかありません.1つは、このパターンが["Gang of Four" book(https://en.wikipedia.org/wiki/Design_Patterns)に記載されているので、それは良いことですソフトウェアパターンの知識について尋ねられたときにインタビューで想定された悪い開発者の答え)。もう1つは、本書の原著者が後で意見を逆転し、それを避けるべき反パターンと宣言したと述べている。 – Sven

+0

@Sven - 質問は、「PHPのどこでもオブジェクトを利用できるようにするには、どのような方法が好ましいのですか?これは多くの有効な回答の1つです。私はあなたに同意していません - 私はシングルトンがこれを行うための最良の方法だとは思わなかったと言及しませんでしたか?小さなアプリケーションで単純なグローバルコンフィグレーションクラスのようなものは、これを実行する最も良い方法かもしれません。範囲が広い場合はおそらくそうではないでしょう。あなたがそう思っているなら、あなたは代替方法を投稿することを歓迎します。 :-) –

関連する問題