Composite

object structural pattern

From: Gang of Four (p. 163)

"Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly."

The key to this pattern is that it allows clients to ignore the difference between compositions of objects and individual objects. When a request is sent down the tree, if the recipient is a single object, the request is handled directly. If the recipient is a composite object, it forwards the request to its children. The client does not and should not know whether they are dealing with individual objects or composite objects.

Pros:

  • Clients can treat composite and individual objects uniformly.
  • It is easy to create new kinds of components.

Cons:

  • Component design can be overly generalized, making it difficult to distinguish between different types of components

Example

Component (defines interface)

class AbstractNode
  def ping
    raise NotImplementedError
  end

  def add(node)
    raise NotImplementedError
  end

  def remove(node)
    raise NotImplementedError
  end

  def nodes
    raise NotImplementedError
  end
end

'Leaf' (individual node)

class Node < AbstractNode
  def ping
    puts "pong!"
  end

  def add(node)
    raise NodeError, "Not a node cluster"
  end

  def remove(node)
    raise NodeError, "Not a node cluster"
  end

  def nodes
    raise NodeError, "Not a node cluster"
  end
end

class NodeError < StandardError
end

Composite (group of nodes)

class NodeCluster < AbstractNode
  def initialize
    @nodes = []
  end

  # This request is forwarded to all children
  def ping
    @nodes.each { |n| n.ping }
  end

  def add(node)
    @nodes << node
  end

  def remove(node)
    @nodes.reject { |n| n == node }
  end

  def nodes
    @nodes
  end
end

Implementation

root = NodeCluster.new
root.add(Node.new)
root.add(Node.new)
root.add(NodeCluster.new)
root.nodes.last.add(Node.new)
root.ping # should print 'pong!' 3 times, one for each Node

results matching ""

    No results matching ""