Composite Design Pattern in Scala

1. Definition

The Composite Design Pattern allows you to compose objects into tree-like structures to represent whole-part hierarchies. This pattern allows treating individual objects and compositions of objects uniformly.

2. Problem Statement

You have individual objects and compositions of objects. You want a unified interface to treat both uniformly, making it easier to scale and manage the hierarchy of objects.

3. Solution

Use the Composite pattern to define classes for individual objects and composite objects, ensuring both types of objects can be treated through a common interface.

4. Real-World Use Cases

1. Graphic systems where shapes can be composed of simpler shapes.

2. Organizational hierarchies where an employee can either be a manager or a regular staff, but both have common attributes and actions.

3. File system representations with files and directories.

5. Implementation Steps

1. Define a common interface for both primitive and composite objects.

2. Create a class for individual objects that implements the common interface.

3. Create a class for composite objects, which also implements the common interface and manages children, which could be other composites or leaf objects.

6. Implementation in Scala Programming

// Step 1: Define a common interface
trait Component {
  def operation(): String
}
// Step 2: Define leaf objects
class Leaf extends Component {
  def operation(): String = "Leaf"
}
// Step 3: Define composite objects
class Composite extends Component {
  private var children: List[Component] = List()
  def add(child: Component): Unit = {
    children = child :: children
  }
  def remove(child: Component): Unit = {
    children = children.filterNot(_ == child)
  }
  def operation(): String = children.map(_.operation()).mkString(", ")
}
// Client code
object Main extends App {
  val leaf1 = new Leaf
  val leaf2 = new Leaf
  val composite = new Composite
  composite.add(leaf1)
  composite.add(leaf2)
  println(composite.operation())
}

Output:

Leaf, Leaf

Explanation:

1. A common interface Component is defined which has the method operation.

2. Leaf class represents individual objects and implements the Component interface.

3. Composite class can have many children, which could be either Leaf or other Composite objects. It manages its children and when its operation method is called, it delegates to its children.

4. In the client code, two Leaf objects are added to a Composite object. When calling the operation on the Composite, it delegates to its children producing the output "Leaf, Leaf".

7. When to use?

The Composite pattern is useful when:

1. You want to represent part-whole hierarchies of objects.

2. You want clients to be able to ignore the difference between compositions of objects and individual objects.

3. You need a structure where objects can be composed recursively to create a hierarchical tree.


Comments