与嵌套对象的生成器模式

MrW*_*ldo 10 c# design-patterns fluent method-chaining builder-pattern

嗨,我遇到了问题.

我想实现构建器模式以使创建对象更容易.我面临的问题与嵌套对象有关.我想要创建的对象中有一个其他对象的列表,我真的不知道如何解决它.

我希望能够执行以下操作(例如,更简单的对象):

Receipt RestaurantReceipt = new ReceiptBuilder()
.withDate("value")
.withName("value")
.AddItem("value")
    .WithIngredients("value")
    .WithType("value")
.AddItem("value")
    .WithIngredients("value")
    .WithType("value")
.build();
Run Code Online (Sandbox Code Playgroud)

或类似的东西:

Receipt RestaurantReceipt = new ReceiptBuilder()
.withDate("value")
.withName("value")
.AddItem("value", item => {
  .WithIngredients("value")
  .WithType("value")
})
.AddItem("value", item => {
  .WithIngredients("value")
  .WithType("value")
})
.build();
Run Code Online (Sandbox Code Playgroud)

示例应该代表我的情况,尽管如果有多种类型的嵌套对象.

Jam*_*iec 14

给出这样的代码

var rb = new ReceiptBuilder();
var receipt = rb.WithName("Name")
            .WithDate(DateTime.Now)
            .WithItem("Item1", i => i.WithIngredients("Ingredients1"))
            .WithItem("Item2", i => i.WithIngredients("Ingredients1"))
            .Build();
Console.WriteLine(receipt);
Run Code Online (Sandbox Code Playgroud)

您的构建器非常简单,在WithItem构建器方法中使用一些简单谓词,以允许使用者将类似"构建器"模式中的每个项目配置到顶层ReceiptBuilder:

public class ReceiptBuilder
{
    private Receipt r;

    public ReceiptBuilder()
    {
        r = new Receipt();
    }

    public ReceiptBuilder WithName(string name)
    {
        r.Name = name;
        return this;
    }

    public ReceiptBuilder WithDate(DateTime dt)
    {
        r.Date = dt;
        return this;
    }

    public ReceiptBuilder WithItem(string text, Action<ReceiptItemBuilder> itemBuilder)
    {
        var rib = new ReceiptItemBuilder(text);
        itemBuilder(rib);
        r.AddItem(rib.Build());
        return this;
    }

    public Receipt Build()
    {
        return r;
    }
}

public class ReceiptItemBuilder
{
    private ReceiptItem ri;

    public ReceiptItemBuilder(string text)
    {
        ri = new ReceiptItem(text);
    }

    public ReceiptItemBuilder WithIngredients(string ings)
    {
        ri.Ingredients = ings;
        return this;
    }

    // WithType omitted for brevity. 

    internal ReceiptItem Build()
    {
        return ri;
    }
}
Run Code Online (Sandbox Code Playgroud)

工作示例:http://rextester.com/IRR50897