КОМПОНУВАЛЬНИК
Компонувальник - це такий дизайн патерн, який дозволяє нам зберігати деревовидну структуру і працювати однаково із батьками та синами у дереві.
Розглянемо інтерфейс що визначає спільні вимоги до батьків і дітей (:
public interface IDocumentComponent
{
string GatherData();
void AddComponent(IDocumentComponent documentComponent);
}А тепер реалізація одного із листків у нашому дереві - CustomerDocumentComponent, яка вміє збирати кусок XML, базуючись на ID-шці замовника.
public class CustomerDocumentComponent : IDocumentComponent
{
private int CustomerIdToGatherData { get; set; }
public CustomerDocumentComponent(int customerIdToGatherData)
{
CustomerIdToGatherData = customerIdToGatherData;
}
public string GatherData()
{
string customerData;
switch (CustomerIdToGatherData)
{
case 41:
customerData = "Andriy Buday";
break;
default:
customerData = "Someone else";
break;
}
return string.Format("<Customer>{0}</Customer>", customerData);
}
public void AddComponent(IDocumentComponent documentComponent)
{
Console.WriteLine("Cannot add to leaf...");
}
}А тепер реалізація нелисткових компонентів нашого дерева. Зверніть увагу, що в методі GatherData, ми просто ітеруємо по всіх "отприсках" і викликаємо наш основний метод для збору даних.
public class DocumentComponent : IDocumentComponent
{
public string Name { get; private set; }
public List<IDocumentComponent> DocumentComponents { get; private set; }
public DocumentComponent(string name)
{
Name = name;
DocumentComponents = new List<IDocumentComponent>();
}
public string GatherData()
{
var stringBuilder = new StringBuilder();
stringBuilder.AppendLine(string.Format("<{0}>", Name));
foreach (var documentComponent in DocumentComponents)
{
documentComponent.GatherData();
stringBuilder.AppendLine(documentComponent.GatherData());
}
stringBuilder.AppendLine(string.Format("</{0}>", Name));
return stringBuilder.ToString();
}
public void AddComponent(IDocumentComponent documentComponent)
{
DocumentComponents.Add(documentComponent);
}
}Клеїмо частинки докупи:
var document = new DocumentComponent("ComposableDocument");
var headerDocumentSection = new HeaderDocumentComponent();
var body = new DocumentComponent("Body");
document.AddComponent(headerDocumentSection);
document.AddComponent(body);
var customerDocumentSection = new CustomerDocumentComponent(41);
var orders = new DocumentComponent("Orders");
var order0 = new OrderDocumentComponent(0);
var order1 = new OrderDocumentComponent(1);
orders.AddComponent(order0);
orders.AddComponent(order1);
body.AddComponent(customerDocumentSection);
body.AddComponent(orders);
string gatheredData = document.GatherData();
Console.WriteLine(gatheredData);Вивід певно схожий на XML, принаймні я хотів щоб він був таким.
<ComposableDocument>Варто добавити, що GoF-хлопці пропонують також методи Remove(Component) та GetChild(int) у інтерфейсі компоненту, тому можливо вам захочеться їх добавити. Одне хочу сказати - ніколи не зациклюєйтися на якихось прикладах і однотипних поясненнях. Ваші потреби можуть дещо відрізнятися від того що описано як дизайн патерн, але в той же час воно вам ідеально підходить, просто у вас якийсесь вироджене або ускладнене застосування.
<Header><MessageTime>8:47:23</MessageTime></Header>
<Body>
<Customer>Andriy Buday</Customer>
<Orders>
<Order>Kindle;Book1;Book2</Order>
<Order>Phone;Cable;Headset</Order>
</Orders>
</Body>
</ComposableDocument>
Моя табличка Патернів

Позитивно:) Спасибо!
ВідповістиВидалитиТа тобі дякую!
ВідповістиВидалити