drozzy drozzy - 2 months ago 12
Java Question

Composite design pattern in Scala?

In java I can implement the composite design pattern as follows:

interface Component{
void operation();

}

class Composite implements Component{
@override
public void operation(){
for(Child child in children){
child.operation();
}
}

public void add(Component child){//implementation}
public void remove(Component child){//implementation}
public void getChild(int index);
}

class Leaf implements Component{
@override
public void operation(){
//implementation
}
}


How can I write it in scala? In particular I am having trouble understanding how to write an interface and implement it?

Answer

In Scala, a Trait without any concrete methods is just an interface. So a direct translation would be:

trait Component { def operation(): Unit }

class Composite extends Component {
  def operation() = children foreach { _.operation() }
  def add(child: Component) = ...
  def remove(child: Component) = ...
  def getChild(index: Int) = ...
}

class Leaf extends Component {
  def operation() = ...
}

Though if you want more idiomatic Scala, I'd recommend something like this as a definition for Composite:

class Composite extends Component {
  def operation() = children foreach { _.operation() }
  def +=(child: Component) = ...
  def -=(child: Component) = ...
  def apply(index: Int) = ...
}

To be used as:

val comp = new Composite
comp += child1
comp += child2
comp -= child1
val firstChild = comp(0)

If you want to take this to a logical conclusion, I'd advocate building the whole composite structure as an immutable Directed Acyclic Graph (though I appreciate that this often isn't possible):

case class Composite(children: Component*) extends Component {
  def operation() = children foreach { _.operation() }
}

val comp = Composite(child1, Composite(child2, child3), child4)