web-dev-qa-db-ja.com

多くのパラメーターを持つ不変オブジェクトをどのように作成しますか?

不変オブジェクトを作成する必要がありますが、次のように機能するにはいくつかのパラメーターが必要です。

class FooRepo
{
    public string ConnectionStringName { get; }
    public string SchemaName { get; }
    public string TableName { get; }
    public Dictionary<string, int> ColumnLengths { get; }
    public Dictionary<Type, SqlDbType> TypeMappings { get; }

    // some queries...
    public IEnumerable<string> GetStrings(object param1) { ... }
}

コンストラクタを介してそれらをすべて渡すにはパラメータが多すぎることがわかりました(後で追加する可能性があります)。

セットアップ後にオブジェクトをロックするという考えも、よく聞こえません。

FooBuilderを作成することを考えましたが、これはhugeコンストラクタを非表示にするだけです。

私が考えることができる唯一の適切な解決策は、ColumnLengthsTypeMappingsなどのいくつかのプロパティのデフォルト値を定義し、ユーザーが元のクラスから派生することでそれらをオーバーライド/カスタマイズできるようにすることです。

あなたは何と言うでしょう?または、そのようなタスクにはもっと良い方法がありますか?

2
t3chb0t

FooRepoに巨大なコンストラクター引数リストを持たせる代わりに、クラスが「大きすぎる」(最初にチェックする必要がある)と仮定します。 、変更可能なDTOオブジェクトを「ヘルパーオブジェクト」の形式として利用することで、値を渡すことができます。これはクラスFooRepoDTOであるか、または ビルダーパターン に従う場合、FooRepoBuilder自体である可能性があります(これにより、渡されたすべてのデータへのアクセスを提供する必要があります「Set ...」メソッド。

2
Doc Brown

あなたはコンストラクタを介してそれらを渡します。それがあなたのコンストラクタが大きすぎることを意味しているなら、おそらくあなたの巨大なクラスはそれほど巨大ではないはずです。

世界には、5つ以上の独立しているが、まとまりのある要素を持つものはほとんどありません。

8
Telastyn

OK、わかったと思いますが、origialビルダーパターンとは少し異なります。ビルダーが不変オブジェクト内にネストされている場合は、実際のオブジェクトに対してプライベートのままであっても、そのプロパティにアクセスしてそれらを設定できます。

class Foo
{
    public Foo() {} 

    public string Bar { get; private set; }

    public string Qux { get; }

    public class Builder
    {
        private Foo _foo = new Foo();
        private Builder() {}

        public static Builder Create() 
        {
            return new Builder();
        }

        public Builder Bar(string bar) 
        {
            _foo.Bar = bar;
            return this;
        }

        public Foo ToFoo()
        {
            return new Foo() 
            {
                Bar = _foo.Bar
            };
        }
    }
}

使用法:

var foo = Foo.Builder.Create().Bar("baz").ToFoo();
var bar = foo.Bar;
1
t3chb0t