Accueil / Tutoriels / Composite : simplifier la gestion des structures hiérarchiques en programmation web
Composite : simplifier la gestion des structures hiérarchiques en programmation web
Publié le 9 Juin 2025Le design pattern Composite est un grand classique des architectures logicielles robustes. C’est un outil redoutablement efficace pour modéliser des structures hiérarchiques complexes. Arborescences, systèmes de permissions, éléments imbriqués d’un DOM virtuel : autant de cas concrets où ce pattern révèle toute sa puissance.
Si vous êtes développeur web, vous avez probablement déjà rencontré un moment où il fallait traiter des objets à la fois individuels et composites, tout en leur appliquant un traitement uniforme. Le pattern Composite est précisément conçu pour ce genre de problème. Voyons ensemble pourquoi il est pertinent, comment l'utiliser intelligemment.
Principe du pattern Composite
Exemples d’utilisation en programmation web
Menus de navigation dynamiques
Systèmes de permissions hiérarchiques
Points d’attention
Implémenter le pattern Composite
Voici un exemple en Go :
package html
import "strings"
type Component interface {
Render() string
}
type Text struct {
Content string
}
func (t *Text) Render() string {
return "" + t.Content + ""
}
type Image struct {
Src string
}
func (i *Image) Render() string {
return "
"
}
type Container struct {
Children []Component
}
func (c *Container) Add(child Component) {
c.Children = append(c.Children, child)
}
func (c *Container) Render() string {
var sb strings.Builder
sb.WriteString("")
for _, child := range c.Children {
sb.WriteString(child.Render())
}
sb.WriteString("")
return sb.String()
}
package main
import (
"fmt"
"designpatterns/composite/html"
)
func main() {
root := &html.Container{}
root.Add(&html.Text{Content: "Bienvenue sur mon site"})
root.Add(&html.Image{Src: "/img/logo.png"})
subContainer := &html.Container{}
subContainer.Add(&html.Text{Content: "Sous-section"})
subContainer.Add(&html.Image{Src: "/img/illustration.jpg"})
root.Add(subContainer)
fmt.Println(root.Render())
}
Le même exemple en PHP :
namespace Practice\DesignPatterns\Composite;
interface ComponentInterface
{
public function render(): string;
}
namespace Practice\DesignPatterns\Composite;
class Text implements ComponentInterface {
private string $content;
public function __construct(string $content) {
$this->content = $content;
}
public function render(): string {
return "{$this->content}";
}
}
namespace Practice\DesignPatterns\Composite;
class Image implements ComponentInterface {
private string $src;
public function __construct(string $src) {
$this->src = $src;
}
public function render(): string {
return "
src}\" />";
}
}
namespace Practice\DesignPatterns\Composite;
class Container implements ComponentInterface {
private array $children = [];
public function add(ComponentInterface $component): void {
$this->children[] = $component;
}
public function render(): string {
$html = "";
foreach ($this->children as $child) {
$html .= $child->render();
}
$html .= "";
return $html;
}
}
declare(strict_types=1);
use Practice\DesignPatterns\Composite\Container;
use Practice\DesignPatterns\Composite\Image;
use Practice\DesignPatterns\Composite\Text;
require "./vendor/autoload.php";
$root = new Container();
$root->add(new Text("Bienvenue sur mon site"));
$root->add(new Image("/img/logo.png"));
$subContainer = new Container();
$subContainer->add(new Text("Sous-section"));
$subContainer->add(new Image("/img/illustration.jpg"));
$root->add($subContainer);
echo $root->render();