2016-07-20 10 views
6

Привет, я застрял в проблеме.Рисунок построителя с вложенными объектами

Я хочу реализовать шаблон строителя, чтобы упростить создание объектов. Проблема, с которой я сталкиваюсь, связана с вложенным объектом. Объект, который я хотел бы создать, содержит в себе список других объектов, и я действительно не знаю, как его решить.

Я хочу быть в состоянии сделать следующее (Упрощенные объекты, например):

Receipt RestaurantReceipt = new ReceiptBuilder() 
.withDate("value") 
.withName("value") 
.AddItem("value") 
    .WithIngredients("value") 
    .WithType("value") 
.AddItem("value") 
    .WithIngredients("value") 
    .WithType("value") 
.build(); 

Или что-то вроде:

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

Пример должен быть репрезентативным для моей ситуации, хотя, если есть более чем один тип вложенного объекта.

+1

Что делает ваш текущий код для 'ReceiptBuilder' взгляда л Айк? Какова структура элементов, которые вы пытаетесь добавить с помощью «AddItem»? – Jamiec

+0

Является ли общий трюк не возвращать экземпляр как возвращаемое значение из этих операций? Итак, почему бы не '' ... .AddFoo (new Foo(). WithIngredient ("value"). WithType ("value")). ... ''? Просто повторите шаблон для этих подтипов и используйте специальные функции/свойства Add-functions/sub-collection. – BitTickler

+0

Было бы полезно увидеть класс «Получение» – konkked

ответ

6

Учитывая подобного код

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); 

Вашего строитель довольно просто, используя несколько простых предикатов внутри метода AddItem строителя, чтобы позволить потребителю настроить каждый элемент в подобном «строителе» образец к началу уровень 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; 
    } 
} 

Рабочий пример: http://rextester.com/IRR50897