web-dev-qa-db-ja.com

コンストラクター引数のラッピング

約25個のサブクラスを持つ基本クラスを考えると、基本コンストラクターに引数を追加するのは面倒であることがわかりました。

protected AbstractController(Service1 s1, Service2 s2, Service3 s3){ ... }
public Concrete1Controller(Service1 s1, Service2 s2, Service3 s3) : base(s1, s2, s3)
public Concrete2Controller(Service1 s1, Service2 s2, Service3 s3) : base(s1, s2, s3)

ベースコントローラーに渡すさらに別のオブジェクトが必要になったので、ラッパークラスの導入と、(ほとんどの)具象インスタンスのコンストラクターで必要なパラメーターが1つだけになるようにリファクタリングすることについて議論しています。

public class ServiceLayer
{
    public Service1 S1 {get; private set; }
    public Service2 S2 {get; private set; }
    public Service3 S3 {get; private set; }

    public ScheduledReportServices(Service1 s1, Service2 s2, Service3 s3)
    {
        S1 = s1;
        S2 = s2;
        S3 = s3;
    }
}

これでかなりクリーンアップできます。

protected AbstractController(ServiceLayer sl){ ... }
public Concrete1Controller(ServiceLayer sl) : base(sl)
public Concrete2Controller(ServiceLayer sl) : base(sl)

これが混乱を減らす量を考えると、私はそもそもこれを行わなかったためのドープであるか、この種のアプローチに対して有効な議論があります。

私は、a)この「パターン」が何と呼ばれるかを知り、b)それを後悔するかどうか、もしそうなら、なぜですか?

3
Joe

a) 'Introduce/Extract Parameter Object'リファクタリング を実行しています。

b)後悔するかどうかは言えません。これのすべてのインスタンスが例外なくサービスs1-s3を必要とする場合、これは適切なリファクタリングのように見えます。

このcanは、パラメータオブジェクトに注意しないと、望ましくない依存関係へのゲートを開くことができます。これが大きな依存関係になるのを防ぐために、今後は無関係な参照を組み合わせないようにしてください。

4

これには本質的に何も問題はありません。過去に、パラメーターを渡すよりも、SomeClassCreateInfoクラスを画像に追加する方が論理的である場合がいくつかありました。

それで、いつそれをするのですか?

これは本質的に答えるのが難しい質問であり、大部分は状況に応じたものになります。通常、Parameter-Wrapper/CreateInfoクラスが必要な場合に明らかになります。しかし、時には、デザインに問題があることを示している可能性もあります。あなたの場合、抽象コントローラーは一連のサービスにアクセスする必要があります。この情報を提供する他の方法はありますか?

1
Moo-Juice