3

私のプログラムでは、一部のオブジェクトには他のオブジェクト(依存関係)が必要であり、作成パターンとしてFactoryを使用しています。

では、単純な依存関係の問題を解決するにはどうすればよいですか?

これは、問題を解決するために私が行っていることの例です。必要なオブジェクトをCreateメソッドに送信することがひどく間違っているのではないかどうかを知りたいです。

//AbstractBackground
// - SpecialBackground
// - ImageBackground
// - NormalBackground
class Screen{
    List<AbstractBackground> list;
    Cursor cursor;
    ContentManager content;

    public void load(string[] backgroundTypes){
        //is this okay? --------------->
        AbstractBackground background = BackgroundFactory.Create(backgroundTypes[0], cursor, content);
        list.add(background);
    }
}

class BackgroundFactory{
    static public AbstractBackground Create(string type, Cursor cursor, ContentManager content){

        if( type.Equals("special") ){
            return new SpecialBackground(cursor, content);
        }

        if( type.Equals("image") ){
            return new ImageBackground(content);
        }

        if( type.Equals("normal") ){
            return new NormalBackground();
        }
    }
}
4

3 に答える 3

5

機能的ですが、タイプを追加すると面倒になる場合があります。
単純なファクトリに対する私の個人的な好みによると、実装は次のようになります。

enum BackgroundFactoryType
{
  Special,
  Image,
  Normal,
}

static class BackgroundFactory{

  static Dictionary<BackgroundFactoryType, Func<Cursor, ContentManager, AbstractBackground>> constructors;

  static BackgroundFactory()
  {
    //initialize the constructor funcs
    constructors = new Dictionary<BackgroundFactoryType, Func<Cursor, ContentManager, AbstractBackground>>();
    constructors.Add(BackgroundFactoryType.Special, (cursor, content) => new SpecialBackground(cursor, content));
    constructors.Add(BackgroundFactoryType.Image, (_, content) => new ImageBackground(content));
    constructors.Add(BackgroundFactoryType.Normal, (_, __) => new NormalBackground());
  }

  static public AbstractBackground Create(BackgroundFactoryType type, Cursor cursor, ContentManager content)
  {
    if (!constructors.ContainsKey(type))
      throw new ArgumentException("the type is bogus");

    return constructors[type](cursor, content);
  }
}

または、単純に次のことを行うことができます。

static class BackgroundFactory{

  static public AbstractBackground Create(BackgroundFactoryType type, Cursor cursor, ContentManager content)
  {
    switch (type)
    {
      case BackgroundFactoryType.Special:
        return new SpecialBackground(cursor, content);
      case BackgroundFactoryType.Image:
        return new ImageBackground(content);
      case BackgroundFactoryType.Normal:
        return new NormalBackground();
      default:
        throw new ArgumentException("the type is bogus");
    }
  }
}

このアプローチの優れた副作用の1つは、ハードコーディングする代わりにこの構成を駆動するために少しの作業が必要になることです。

于 2012-12-31T09:05:58.387 に答える
4

簡単な答え、それはよさそうだ。これを抽象的に考えると、createメソッドを介してオブジェクトをコンストラクターに注入していることになります。このテクニックには何の問題もありません。私がお勧めするものです。

後で、実装を変更する必要がある場合は、何も壊すことなく、必要に応じて他のcreateメソッドを作成できます。

于 2012-12-31T08:50:43.103 に答える
1

依存関係ツリーが大きくなると、作成するファクトリメソッドが複雑になることを除いて、コードにはそれほど醜いものはありません。IoCさまざまな明確な依存関係を持つ型を因数分解するには、おそらくベースのファクトリを選択する方がよいでしょう。依存関係をコンテナーに登録することにより、必要な依存関係を持つコンストラクターが自動的に挿入されます。

于 2012-12-31T08:54:03.320 に答える