Design Patterns Handbook
  • Introduction
  • Creational Patterns
    • Builder
    • Factory
    • Abstract Factory
    • Factory Method
    • Prototype
    • Singleton
    • Object Pool
    • Revealing Constructor
  • Structural Patterns
    • Adapter
    • Composite
    • Proxy
    • Flyweight
    • Facade
    • Bridge
    • Decorator
    • Private Class Data
  • Behavioral Patterns
    • Template Method
    • Mediator
    • Chain Of Responsibility
    • Observer
    • Strategy
    • Command
    • State
    • Visitor
    • Memento
    • Interpreter
    • Null Object
    • Iterator
    • Middleware
  • Clean Code Patterns
    • Extract Method
    • Clarify Responsibility
    • Remove Duplications
    • Keep Refactoring
    • Always Unit Test
    • Create Data Type
    • Comment to Better Name
    • Consistent Naming
    • If-else over ternary operator
    • Composition over Inheritance
    • Too Many Returns
    • Private to Interface
  • Anti Patterns
    • Big Ball of Mud
    • Singleton
    • Mad Scientist
    • Spaghetti Code
    • It Will Never Happen
    • Error Codes
    • Commented Code
    • Abbreviations
    • Prefixes
    • Over Patternized
    • Generic Interface over Function
Powered by GitBook
On this page
  • Example - Simple Composite
  • Example - Composite with an interface
  • Complex example with simple algorithm

Was this helpful?

  1. Structural Patterns

Composite

When ever we need to a tree structure, we use composite pattern.

Example - Simple Composite

There is a way to create really simple tree structure using composite patter (but we have to omit few classes in order to make it really simplistic).

class TreeNode {

    private String name;
    private List<TreeNode> children = new ArrayList<>();

    public TreeNode(String name) {
        this.name = name;
    }

    public void addChild(TreeNode child) {
        children.add(child);
    }

    public boolean isLeaf() {
        return children.size() == 0;
    }
}

Now we can create a tree using just TreeNode.

TreeNode root = new TreeNode("Root");
root.addChild(new TreeNode("Node 1"));
root.addChild(new TreeNode("Leaf 1"));

Example - Composite with an interface

Here is an example of composite pattern. Leaf can't have any children. Node can contain multiple implementations of Component interface. Node class is enabling the tree structure.

interface Component {
    void sayYourName();
}

class Node implements Component {

    private String name;

    private List<Component> elements = new ArrayList<>();

    public Node(String name) {
        this.name = name;
    }

    @Override
    public void sayYourName() {
        System.out.println(name);
    }

    public void add(Component component) {
        elements.add(component);
    }
}

class Leaf implements Component {

    private String name;

    public Leaf(String name) {
        this.name = name;
    }

    @Override
    public void sayYourName() {
        System.out.println(name);
    }
}

Here is how to create a tree using the classes above.

Node root = new Node("Root");
root.add(new Node("Node 1"));
root.add(new Leaf("Leaf 1"));

Complex example with simple algorithm

A mathematical formula can be represented as a tree. Lets try it out and see how composite works in real life.

interface ArithmeticExpression {
    int evaluate();
}

class CompositeOperand implements ArithmeticExpression {

    private String operator;
    private List<ArithmeticExpression> expressions = new ArrayList<>();

    public CompositeOperand(String operator) {
        this.operator = operator;
    }

    public void add(ArithmeticExpression expression) {
        expressions.add(expression);
    }

    @Override
    public int evaluate() {

        List<Integer> evaluated = new ArrayList<>();

        for (ArithmeticExpression expression : expressions) {
            evaluated.add(expression.evaluate());
        }

        Integer result = null;
        for (Integer number : evaluated) {
            if (operator.equals("*")) {
                if (result == null) {
                    result = number;
                } else {
                    result *= number;
                }
            } else if (operator.equals("+")) {
                if (result == null) {
                    result = number;
                } else {
                    result += number;
                }
            } else if (operator.equals("-")) {
                if (result == null) {
                    result = number;
                } else {
                    result -= number;
                }
            }
        }

        return result;
    }
}

class NumericOperand implements ArithmeticExpression {

    private int number;

    public NumericOperand(int number) {
        this.number = number;
    }

    @Override
    public int evaluate() {
        return number;
    }
}

Now we can construct mathematical formula. We are going to use this ((7+3)*(5−2)).

// create root
CompositeOperand multiply = new CompositeOperand("*");

// create +
CompositeOperand firstSum = new CompositeOperand("+");
firstSum.add(new NumericOperand(7));
firstSum.add(new NumericOperand(3));
multiply.add(firstSum);

// create -
CompositeOperand secondSum = new CompositeOperand("-");
secondSum.add(new NumericOperand(5));
secondSum.add(new NumericOperand(2));
multiply.add(secondSum);

// evaluate all children, then do math operation
int result = multiply.evaluate();
System.out.println(result);

The program will print out the following.

30
PreviousAdapterNextProxy

Last updated 5 years ago

Was this helpful?