6

そこで、Factory Design パターンと Dependency Injection を併用することにしました。

class ClassA
{        
    Object *a, *b, *c;
    public:
    ClassA(Object *a, Object *b, Object *c) :
    a(a), b(b), c(c) {}
};

class ClassB : public ClassA
{        
    Object *d, *e, *f;
    public:
    ClassB(Object *a, Object *b, Object *c, Object *d, Object *e, Object *f) :
    ClassA(a, b, c), d(d), e(e), f(f) {}
};

ここでの問題は、classB のコンストラクターに対する引数が多すぎることです。これは単一の継承レイヤーの例ですが、継承レイヤーが深くなり始め、各レイヤークラスを構築するためにさらに多くのオブジェクトが必要になると、最上位レイヤーのコンストラクターは作成するためにあまりにも多くの引数を必要としなくなります!

コンストラクターの代わりにセッターを使用できることはわかっていますが、他に方法はありますか?

4

3 に答える 3

6

セッターは、エラーが発生しやすい部分的に構築されたオブジェクトになるため、そのようなものにはお勧めしません。多くのパラメーターを必要とするオブジェクトを構築するための一般的なパターンは、ビルダーの使用です。ClassBBuilder の役割は、ClassB オブジェクトを作成することです。ClassB コンストラクターを非公開にし、ビルダーのみがフレンド関係を使用して呼び出すことができるようにします。さて、ビルダーはどういうわけかこのように見えることができます

ClassBBuilder {
  public:
    ClassBBuilder& setPhoneNumber(const string&);
    ClassBBuilder& setName(consg string&);
    ClassBBuilder& setSurname(const string&);
    ClassB* build(); 
} 

そして、ビルダーを次のように使用します。

ClassB* b = ClassBBuilder().setName('alice').setSurname('Smith').build();

build() メソッドは、すべての必要なパラメーターが設定されていることを確認し、適切に構築されたオブジェクトまたは NULL を返します。部分的に構築されたオブジェクトを作成することはできません。多くの引数を持つコンストラクターがまだありますが、それは非公開であり、1 か所でのみ呼び出されます。クライアントには表示されません。Builder メソッドは、各パラメーターの意味も適切に文書化しています (ClassB('foo', 'bar') が表示された場合、コンストラクターをチェックして、どのパラメーターが名前で、どのパラメーターが姓であるかを判断する必要があります)。

于 2012-09-06T07:37:22.420 に答える
1

これは C++ の問題の 1 つです (これを問題と呼べる場合)。ctor のパラメータ数を最小限に抑える以外に解決策はありません。

アプローチの 1 つは、次のような props 構造体を使用することです。

struct PropsA
{
    Object *a, *b, *c;
};

class ClassA
{
    ClassA(PropsA &props, ... other params);
};

これは明らかなようですが、私はこれを数回使用しました。多くの場合、パラメータのいくつかのグループが関連していることがわかります。この場合、構造体を定義するのが理にかなっています。

この種の私の最悪の悪夢は、薄いラッパー クラスでした。ベースのメソッドとデータ フィールドには直接アクセスできますが、すべての ctor を複製する必要があります。10 個以上の ctor がある場合、ラッパーの作成が問題になり始めます。

于 2012-09-04T17:37:22.070 に答える