2009-07-20 12 views
16

次のコードはチュートリアル(http://net.tutsplus.com/php/creating-a-php5-framework-part-1/)のものであり、私のものではありません。レジストリデザインパターン...良いか悪いですか?

私はこのコードについていくつか質問がある

...

  • 記事は、それが「レジストリのデザインパターン」を使用していると主張。業界でのこのデザインの普遍的な名前ですか?
  • もっと良い選択肢になるもう一つの同様のパターンがありますか?
  • このパターンは、MVCフレームワークのコンテキストで実装するのが良い方法と考えられますか?

MVCフレームワークの独自の実装でこのデザインパターンを使用する必要があるかどうかを知りたいだけです。ありがとう!

<?php 
/** 
* The PCARegistry object 
* Implements the Registry and Singleton design patterns 
* @version 0.1 
* @author Michael Peacock 
*/ 
class PCARegistry { 

/** 
* Our array of objects 
* @access private 
*/ 
private static $objects = array(); 

/** 
* Our array of settings 
* @access private 
*/ 
private static $settings = array(); 

/** 
* The frameworks human readable name 
* @access private 
*/ 
private static $frameworkName = 'PCA Framework version 0.1'; 

/** 
* The instance of the registry 
* @access private 
*/ 
private static $instance; 

/** 
* Private constructor to prevent it being created directly 
* @access private 
*/ 
private function __construct() 
{ 

} 

/** 
* singleton method used to access the object 
* @access public 
* @return 
*/ 
public static function singleton() 
{ 
    if(!isset(self::$instance)) 
    { 
     $obj = __CLASS__; 
     self::$instance = new $obj; 
    } 

    return self::$instance; 
} 

/** 
* prevent cloning of the object: issues an E_USER_ERROR if this is attempted 
*/ 
public function __clone() 
{ 
    trigger_error('Cloning the registry is not permitted', E_USER_ERROR); 
} 

/** 
* Stores an object in the registry 
* @param String $object the name of the object 
* @param String $key the key for the array 
* @return void 
*/ 
public function storeObject($object, $key) 
{ 
    require_once('objects/' . $object . '.class.php'); 
    self::$objects[ $key ] = new $object(self::$instance); 
} 

/** 
* Gets an object from the registry 
* @param String $key the array key 
* @return object 
*/ 
public function getObject($key) 
{ 
    if(is_object (self::$objects[ $key ])) 
    { 
     return self::$objects[ $key ]; 
    } 
} 

/** 
* Stores settings in the registry 
* @param String $data 
* @param String $key the key for the array 
* @return void 
*/ 
public function storeSetting($data, $key) 
{ 
    self::$settings[ $key ] = $data; 


} 

/** 
* Gets a setting from the registry 
* @param String $key the key in the array 
* @return void 
*/ 
public function getSetting($key) 
{ 
    return self::$settings[ $key ]; 
} 

/** 
* Gets the frameworks name 
* @return String 
*/ 
public function getFrameworkName() 
{ 
    return self::$frameworkName; 
} 


} 

?> 
+0

LOL ...私は投票して投票しました。私の質問は誰かのために十分ではないと思います。 –

答えて

25

記事では、「レジストリのデザインパターン」を使用していると主張。業界でのこのデザインの普遍的な名前ですか?

はい、実装は明らかに異なる場合があります。基本的に、レジストリは共有オブジェクトのコンテナです。本当に基本的なバージョンでは、配列を使うことができます。したがって、変数$GLOBALSはレジストリと呼ぶことができます。

もっと良い選択肢がありますか?

レジストリには2つのバリエーションがあります。グローバルレジストリがあります(これは最も一般的ですが、これはその例です)。そして、ローカルレジストリがあります。ローカルレジストリは、グローバルシンボル(静的クラス、シングルトンなど)で取得するのではなく、必要なオブジェクトに渡されます。ローカルレジストリの結合度は低くなりますが、やや抽象度が高いので、そこにはトレードオフがあります。

さらに進んで、すべての依存関係を必要とするオブジェクトに明示的に渡す完全な依存関係注入を使用することもできます。これは、大規模なアプリケーションでは少し面倒です。これを、クラスがどの依存関係にあるかを「知っている」コードである依存関係注入コンテナと組み合わせることができます。これは、ローカルレジストリよりもさらに複雑ですが、カップリング度は非常に低いです。

このパターンは、MVCフレームワークのコンテキストで実装することを推奨しますか?

これは一般的な方法です。それが良いか悪いかが判断の呼び出しです。個人的には、私はデカップリングの結果、いくらかの複雑さを受け入れるつもりですが、ymmv。

5

私は総称的に言って、は実際にはのような "悪いパターン"とは言えません。つまり、いくつかのテクニックは他よりも控えめに使用されるべきであり、グローバルレジストリの概念はしばしばエレガントではないものです。問題は、与えられたオブジェクト間の依存関係は、依存関係を提供することによる戦略化の間接的な指示ではなく、単にグローバル変数を使うことに似ている名前ベースのアドレッシングによって処理されるということです。これは一般に依存性注入

これがソフトウェアの再利用と柔軟性にどのように影響するかは、実際は非常に明確です。認証のためにOAuth2プロバイダと統合するリクエストハンドラを考えてみましょう。このOAuth2プロバイダへのリクエストを作成するために明確に定義されたインタフェースを持つオブジェクトを定義する場合、同じインタフェースを実装する別のオブジェクトを作成することで、今後プロバイダを変更することができます。

ここで、最初の実装でFacebookにアクセスする必要があるとします。しかし、来週は、Facebookよりも仕様に準拠した方法でOAuth2を実装しているYahooをサポートする必要があり、実際にJSONを名前の値のペアではなく認証トークンの要求で使用する必要があるという決定を下す。そして、その上に、保持する必要のあるURLとキーとその他のペアのペアがあります。

レジストリパターンまたはサービスロケータパターンを使用して名前で認証プロバイダを検索していた場合は、問題が発生します。一度に両方をサポートできるように、コードをコピーしてマイナーな変更を加えるか、キーを渡したり、すべての場所にハッシュテーブルを追加してこれらの要素をすべて見つけ出し、これらの差異を検出するなどの別のソリューションを見つける必要があります。一方、依存関係注入を使用した場合は、認証トークンを解析する微妙な違いを実装する認証プロバイダの別の実装を作成し、そのオブジェクトを使用して既にテスト済みのリクエストハンドラの新しいインスタンスを作成します。それを新しい場所に展開します。

間接指示は作業を節約し、必要なコードの量を減らし、最終的にソフトウェアをより安価に、より速く、より速くしました。

これで、2つのパターンがでない場合は、直接と交換することがあります。たとえば、イベントハンドラをXMLドキュメントのノードに接続するフレームワークを構築しているとします。 XPathまたはJQueryのCSSセレクタの実装を使用して、XMLドキュメント内のノードの位置を記述します。しかし、イベントハンドラをアタッチするには、いくつかのコードを参照する必要があります。できればオブジェクトのいくつかのメソッドを参照することになります。名前を付けずにこの「オブジェクト」を見つける方法はないので、サービスロケータが必要になります。しかし、この例でも、名前がであることを指定するものはありません。です。

ここでローカルサービスロケータまたはローカルレジストリを作成することは、このような問題の妥当な解決策です。同じアプリケーションに2つのレジストリインスタンスが存在する可能性がある場合は、上記の再利用の問題のいくつかを緩和することがあります。

関連する問題