V této části si ukážeme návrhový vzor Composite. Cílem tohoto návrhového vzoru je, aby se s kolekcí objektů pracovalo stejným způsobem jako se samotným objektem.
Návrhový vzor Composite je o tom, že se s kolekcí objektů pracuje stejným způsobem jako s jedním objektem. Pro jeho implementaci se objekty většinou skládají do nějaké stromové struktury.
Composite se tedy hodí, když chceme se skupinou objektů pracovat stejně jako s jedním objektem.
Následující ukázka ukazuje třídu GrafickyObjekt a její podtřídy Kruh a Ctverec. Všechny tyto třídy představují grafický objekt, který může obsahovat jiné grafické objekty. S kolekcí grafických objektů (grafickým objektem skládajícím se z více grafických objektů) můžeme pracovat stejným způsobem jako s jedním grafickým objektem. Přesně tuto vlastnost návrhový vzor Composite představuje.
// třída pro grafický objekt
class GrafickyObjekt {
static pocet = 0;
constructor(nazev="Skupina " + GrafickyObjekt.pocet++) {
// grafický objekt se může skládat z více grafických objektů
this.potomci = [];
this.barva = undefined;
this.nazev = nazev;
}
// pomocná metoda pro získání textové reprezentace objektu
print(buffer, odsazeni) {
// vložení odsazení
buffer.push("*".repeat(odsazeni));
if (odsazeni > 0) buffer.push(" ");
// vložení barvy objektu
if (this.barva) buffer.push(`[${this.barva}] `);
// vložení jména objektu
buffer.push(this.nazev);
// vložení nového řádku
buffer.push("\n");
// zavolání metody print na všechny potomky
for (let potomek of this.potomci)
potomek.print(buffer, odsazeni+1);
}
// metoda pro získání textové reprezentace objektu
toString() {
const buffer = [];
// objekty (tedy i pole) se předávají adresou
// - metoda print pracuje přímo s předaným polem
this.print(buffer, 0);
return buffer.join("");
}
}
class Kruh extends GrafickyObjekt {
constructor(barva) {
super("Kruh");
this.barva = barva;
}
}
class Ctverec extends GrafickyObjekt {
constructor(barva) {
super("Čtverec");
this.barva = barva;
}
}
// vytvoření grafického objektu kresba
const kresba = new GrafickyObjekt();
// přidání kruhu a čtverce (grafických objektů) do kresby
kresba.potomci.push(new Kruh("žlutá"));
kresba.potomci.push(new Ctverec("zelená"));
// vytvoření grafického objektu skupina
const skupina = new GrafickyObjekt();
// přidání grafických objektů do skupiny
skupina.potomci.push(new Ctverec("modrá"));
skupina.potomci.push(new Kruh("fialová"));
// přidání skupiny do kresby
kresba.potomci.push(skupina);
// všimněte si, že se všemi grafickými objekty pracujeme stejným způsobem
// vypsání struktury grafického objektu
console.log(kresba.toString());
// vypíše se:
// Skupina 0
// * [žlutá] Kruh
// * [zelená] Čtverec
// * Skupina 1
// ** [modrá] Čtverec
// ** [fialová] Kruh