The Composite Pattern
is a Gang Of Four structural Design Pattern that helps solve the following problems:
The Composite pattern will describe the following:
Component
interface for both part (Leaf) objects and whole (Composite) objects.Leaf
objects implement the Component
interface directly, and Composite
objects forward requests to their child components.Clients can then work through the Component
interface to treat Leaf
and Composite
objects uniformly.
Leaf
objects perform a request directly, and Composite
objects forward the request to their child components recursively downwards the tree structure. This makes client classes easier to implement, change, test, and reuse.
interface ArmyObject { name: String; operate(): void; } class Team implements ArmyObject { name: String; private _soldiers: ArmyObject[]; constructor(name: String) { this.name = name; this._soldiers = []; } operate(): void { console.log(`Team: ${this.name} operates`); this._soldiers.map((soldier: ArmyObject) => { soldier.operate(); }); } addSoldier(newSoldier: ArmyObject) { const soldiers = this._soldiers.filter((soldier: ArmyObject, index) => { return soldier.name === newSoldier.name; }); if (soldiers.length < 1) { console.log(`Soldier: ${newSoldier.name} comes in ${this.name}`); this._soldiers.push(newSoldier); } else { console.log('The soldier is already in the team'); } } soldierGone(deadSoldier: ArmyObject) { const deads = this._soldiers.map((soldier: ArmyObject, index) => { if (soldier.name === deadSoldier.name) { return index; } }); if (deads.length > 0) { console.log(`Soldier: ${deadSoldier.name} died in the fight`); this._soldiers.slice(deads[0], 1); } else { console.log('No one dies'); } } } class Soldier implements ArmyObject { name: String; constructor(name: String) { this.name = name; } operate() { console.log(`Soldier: ${this.name} soldier operates`); } } (function main() { const team = new Team('Seal Team 6'); const specialSquad = new Team('Seal Team 6 - Special Squad'); const soldierJoe = new Soldier('Joe'); const soldierJames = new Soldier('James'); const soldierRoy = new Soldier('Roy'); team.addSoldier(soldierJoe); team.addSoldier(soldierJames); team.addSoldier(soldierRoy); const specialForceTommy = new Soldier('Tommy'); specialSquad.addSoldier(specialForceTommy); team.operate(); specialSquad.operate(); team.soldierGone(soldierJames); })();
import java.util.ArrayList; /** "Component" */ interface Graphic { //Prints the graphic. public void print(); } /** "Composite" */ class CompositeGraphic implements Graphic { //Collection of child graphics. private final ArrayList<Graphic> childGraphics = new ArrayList<>(); //Adds the graphic to the composition. public void add(Graphic graphic) { childGraphics.add(graphic); } //Prints the graphic. @Override public void print() { for (Graphic graphic : childGraphics) { graphic.print(); //Delegation } } } /** "Leaf" */ class Ellipse implements Graphic { //Prints the graphic. @Override public void print() { System.out.println("Ellipse"); } } /** Client */ public class CompositeDemo { public static void main(String[] args) { //Initialize four ellipses Ellipse ellipse1 = new Ellipse(); Ellipse ellipse2 = new Ellipse(); Ellipse ellipse3 = new Ellipse(); Ellipse ellipse4 = new Ellipse(); //Creates two composites containing the ellipses CompositeGraphic graphic2 = new CompositeGraphic(); graphic2.add(ellipse1); graphic2.add(ellipse2); graphic2.add(ellipse3); CompositeGraphic graphic3 = new CompositeGraphic(); graphic3.add(ellipse4); //Create another graphics that contains two graphics CompositeGraphic graphic1 = new CompositeGraphic(); graphic1.add(graphic2); graphic1.add(graphic3); //Prints the complete graphic (Four times the string "Ellipse"). graphic1.print(); } }