What is Composite Design Pattern?: Composite is a structural design pattern that lets you compose objects into tree structures and then work with these structures as if they were individual objects.
Composite design pattern treats each node in two ways:
1) Composite – Composite means it can have other objects below it.
2) leaf – leaf means it has no objects below it.

Why Composite Design Pattern?: The Composite pattern lets you run a behavior recursively over all components of an object tree. The greatest benefit of this approach is that you don’t need to care about the concrete classes of objects that compose the tree. You don’t need to know whether an object is a simple product or a sophisticated box.
The Composite design pattern can be used to represent an expression in Apex regardless of expression complexity, whilst mitigating the impact of governor limits that can result from recursions.
Problem: Let’s take an example of Employee Hierarchy in a company. and we have to manage these hierarchy.
Solution: Use the Composite pattern when you have to implement a tree-like object structure. Employee hierarchy can be represented as a tree structure, so we can use composite design pattern for this. Let’s understand this by following code example-
public class Employee {
private String name;
private String dept;
private integer salary;
private List<Employee> subordinates;
// constructor
public Employee(String name,String dept, integer sal) {
this.name = name;
this.dept = dept;
this.salary = sal;
subordinates = new List<Employee>();
}
public void add(Employee e) {
subordinates.add(e);
}
public void remove(Employee e) {
for(Integer i = subordinates.size() - 1; i >= 0; i--) {
if(subordinates[i].equals(e)) {
subordinates.remove(i);
}
}
}
public List<Employee> getSubordinates(){
return subordinates;
}
public override String toString(){
return ('Employee :[ Name : ' + name + ', dept : ' + dept + ', salary :' + salary+' ]');
}
}
public class CompositePatternDemo {
public static void validateResult() {
Employee CEO = new Employee('John','CEO', 30000);
Employee headSales = new Employee('Robert','Head Sales', 20000);
Employee headMarketing = new Employee('Michel','Head Marketing', 20000);
Employee clerk1 = new Employee('Laura','Marketing', 10000);
Employee clerk2 = new Employee('Bob','Marketing', 10000);
Employee salesExecutive1 = new Employee('Richard','Sales', 10000);
Employee salesExecutive2 = new Employee('Rob','Sales', 10000);
CEO.add(headSales);
CEO.add(headMarketing);
headSales.add(salesExecutive1);
headSales.add(salesExecutive2);
headMarketing.add(clerk1);
headMarketing.add(clerk2);
//print all employees of the organization
System.debug('CEO:' + CEO);
for (Employee headEmployee : CEO.getSubordinates()) {
System.debug('Head Employee:' + headEmployee);
for (Employee employee : headEmployee.getSubordinates()) {
System.debug('Simple Employee:' + employee);
}
}
}
}
When we execute CompositePatternDemo.validateResult() method, we get following results-

Let’s take another example which is bit complex to understand this-
We will be using composite design pattern to represent expressions. Let’s see the code-
public Interface Expression {
Expression add(Expression expr);
Expression set(String name, Boolean value);
Boolean evaluate();
}
public abstract class Composite implements Expression{
public List<Expression> children {get; private set;}
public Composite(){
this.children = new List<Expression>();
}
public Expression add(Expression expr){
children.add(expr);
return this;
}
public Expression set(String name, Boolean value){
for(Expression expr : children) {
expr.set(name,value);
}
return this;
}
public abstract Boolean evaluate();
public Boolean hasChildren{
get{
return !children.isEmpty();
}
}
}
public class AndComposite extends Composite{
public override Boolean evaluate(){
for(Expression expr : children) {
if(!expr.evaluate()) { //if any of the expression is false, it returns false
return false;
}
}
return true;
}
}
public class OrComposite extends Composite{
public override Boolean evaluate(){
for(Expression expr : children) {
if(expr.evaluate()) { //if any of the expression is true, it returns true
return true;
}
}
return false;
}
}
public class Variable implements Expression {
public String name {
get;
private set;
}
public Boolean value {
get;
private set;
}
public Variable(String name) {
this.name = name;
}
public Expression add(Expression expr) {
return this;
}
public Expression set(String name, Boolean value) {
if (this.name != null && this.name.equalsIgnoreCase(name)) {
this.value = value;
}
return this;
}
public Boolean evaluate() {
return value;
}
}
The examples below illustrate how to use the Expression interface-
Example: 1 AND 2
//1 AND 2
Expression expr = new AndComposite();
expr.add(new Variable('1'));
expr.add(new Variable('2'));
expr.set('1', true).set('2', false);
system.debug(expr.evaluate()); //will print false
Example: 1 OR (2 AND 3)
//1 OR (2 AND 3)
Expression expr = new OrComposite();
expr.add(new Variable('1'));
Expression expr2 = new AndComposite();
expr2.add(new Variable('2'));
expr2.add(new Variable('3'));
expr.add(expr2);
expr.set('1', true).set('2', false).set('3', true);
system.debug(expr.evaluate()); //will print true
For all Design Patterns, please refer this.