Ce este
Șablonul Composite tratează lucrurile individuale și grupurile de lucruri prin aceeași interfață. Un fișier are o dimensiune; un folder plin cu fișiere (și foldere) are și el o dimensiune — așa că amândouă implementează Size(), iar codul care adună dimensiunile nu întreabă niciodată pe care dintre ele îl ține.
Compozitele formează în mod natural arbori: grupurile conțin frunze și alte grupuri, oricât de adânc.
Exemplu: fișiere și foldere
Interfața Item are o singură metodă. Un fișier răspunde cu propria dimensiune; un folder întreabă tot ce se află înăuntru și adună — recursivitatea apare de la sine.
O singură interfață pentru frunză și pentru grup
root.Size() parcurge tot arborele fără nicio verificare de tip: folderului nu îi pasă dacă un element este un fișier de 4 KB sau alt folder care mai ascunde zece.
Ieșire: program Go și rezultatul capturat
package main
import "fmt"
type Item interface {
Size() int
}
type File struct {
name string
size int
}
func (f File) Size() int { return f.size }
type Folder struct {
name string
items []Item
}
// Dimensiunea unui folder este suma a tot ce se află înăuntru — fișiere sau foldere.
func (f Folder) Size() int {
total := 0
for _, item := range f.items {
total += item.Size()
}
return total
}
func main() {
docs := Folder{name: "docs", items: []Item{
File{name: "notițe.txt", size: 4},
File{name: "plan.md", size: 6},
}}
root := Folder{name: "root", items: []Item{
File{name: "readme.md", size: 2},
docs,
}}
fmt.Println("dimensiune docs:", docs.Size(), "KB")
fmt.Println("dimensiune root:", root.Size(), "KB")
}
Când să îl folosești
Folosește-l pentru date în formă de arbore, unde grupurile și elementele individuale răspund la aceleași întrebări — sisteme de fișiere, meniuri cu submeniuri, aranjamente de interfață, organigrame.
Renunță la el pentru liste plate. Un slice cu o buclă nu are nevoie de niciun șablon.
Avantaje și dezavantaje
Avantaje: codul client rămâne simplu și fără ramificații; arborii de orice adâncime vin gratis; tipuri noi de frunze sau de grupuri se conectează la aceeași interfață.
Dezavantaje: interfața comună poate impune frunzelor metode nepotrivite (ce înseamnă „adaugă copil” pentru un fișier?); compozitele foarte generale devin greu de ținut sub control.