1

PHP アプリケーション全体で、コンストラクター依存性注入を実践しています。オブジェクトの作成でコードを散らかしたくなかったので、ファクトリが救助に、または少なくとも私は考えました。

私はコンポーネントをファクトリに接続することに着手し、いくつかのファクトリは他のファクトリを使用して依存関係を取得し始めました。すばらしい、すべての作成コードを 1 か所に保持します。しかし、ファクトリが相互に (または以下のコードのように) 使用を開始すると、循環依存の問題に遭遇しました。これは単純に解決できません。たとえば、私の MapperFactory はそれ自体を使用して、マッパーを他のマッパーに注入します (完全なオブジェクト グラフの「イーガー ロード」を構築するには、相互に必要です)。

class MapperFactory
{   
    public function create($type)
    {
        switch (true) {
            case 'Item':
                $mapper = new ItemMapper(
                    $this->create('Field')  
                );               
                break;
            case 'Field':
                $mapper = new ItemMapper(
                    $this->create('Item')  
                );
                break;
            default:
                throw new Exception('Unknown mapper');
        }
        return $mapper;
    }

}

$mf = new MapperFactory();
$mf->create('Item');

これは単純化された例ですが、アプリケーションが開発されるにつれてますます一般的な問題になります。PHP (xdebug がインストールされている) から返されるエラーは次のとおりです。

Fatal error: Maximum function nesting level of '100' reached, aborting!

PHP が不平を言っている理由を完全に理解してください (TBH が来るとは思いませんでしたが)。

私の質問は、工場の要点を完全に見逃していませんか? 工場を正しく使用していますか?そうではないように思えますが、循環依存関係 (かなり重要ですが) を除けば、ファクトリはすべての構築/配線ロジックをメイン アプリケーションから遠ざけるための洗練されたソリューションです。

4

2 に答える 2

1

依存関係を注入するためにセッターを使用してみることができます。次に、次のように両方のマッパーを作成します。

$itemMapper = new Mapper();
$fieldMapper = new Mapper();
$itemMapper->setRelatedMapper($fieldMapper);
$fieldMapper->setRelatedMapper($itemMapper);

次に、スイッチを使用してマッパーを返します。これにより、オブジェクトを作成する際の循環依存が取り除かれます。

そうは言っても、データベースに接続するための一種の OR/M としてこれを行っている場合は、Doctrine2 や Propel のようなものを調べる必要があります。テスト済みのソリューションがあります。

于 2012-08-13T17:57:09.807 に答える
0

MapperFactorycreateメソッドが無限ループを引き起こしている ようです。

switch(true) {
  case 'Item' : // this will always be selected http://php.net/manual/en/language.types.type-juggling.php
    $mapper = new ItemMapper(
      $this->create('Field'); // Forces loop,
    );

TRUEスイッチが一致を探している場合、ケース操作はブール値でなければなりません

switch(true) {
  case $type == 'Item' :
    // ...
    break;
  case $type == 'Field' :
    // ...
 }
于 2012-08-13T17:57:29.167 に答える