Builder pattern
În multe situații, dorim să construim obiecte sau structuri complexe. Din acest motiv, a fost inventat pattern-ul builder. Acesta ne permite să adăugăm conținut la obiecte pas cu pas, apelând câte o metodă, tehnică numită înlănțuire de metode (method-chaining). În method-chaining, apelăm metoda obiectului și returnăm fie aceeași instanță de obiect, fie o instanță de același tip de obiect.
Un avantaj al acestui pattern este că nu trebuie să inițializăm tot obiectul deodată, ci putem să-l actualizăm în etape. În C#, o modalitate simplă de a implementa acest pattern este prin metode de extensie. Astfel, putem aplica acest pattern și pentru a construi instanțe ale claselor din biblioteci importate, pe care nu le putem modifica, adăugând astfel funcționalități noi la cod deja existent.
Nu în ultimul rând, acest pattern face codul mult mai ușor de citit, dacă metodele sunt denumite corect.
Exemplul de mai jos este un exemplu de builder pattern pentru construirea unui șir de caractere.
public class MyStringBuilder
{
// Avem continutul pe care vrem sa-l modificam
private string _content = "";
// In acest caz avem nevoie doar de o singura primitiva de modificat continutul si
// observati ca returnam instanta proprie
public MyStringBuilder Add(string value)
{
_content += value;
return this;
}
// Actiunea de constructie trebuie sa ne returneze rezultatul dorit
public string Build()
{
return _content;
}
}
public static class MyStringBuilderExtensions
{
// Putem folosi primitive in metodele de extensie si sa implementam metode pentru necesitati specifice cu denumiri sugestive
public static MyStringBuilder AddNewLine(this MyStringBuilder builder)
{
return builder.Add("\r\n");
}
}
Exercițiu - Builder pattern
Folosind exemplul de cod prezentat mai sus, adăugați mai multe metode de extensie astfel încât să funcționeze codul de mai jos:
static class Program
{
static async Task Main(string[] args)
{
var builder = new MyStringBuilder();
builder.Add("Ana")
.AddWords(new List<string>()
{
"are",
"mere"
})
.AddLine("Barnabas are banane")
.AddLines(new List<string>()
{
"Cecilia are cirese",
"Dan are dude"
});
Console.Write(builder.Build());
}
}