Edi Weissmann

I code for fun /* and profit */

Design Patterns and Scala

Scala logo

Overview

A design pattern sometimes represents a language failing. The term “pattern” implies a solution to some kind of recurring problem. Stronger languages can resolve these duplications more easily by using language features and not secondary constructs such as patterns. For a developer accustomed to design patterns in Java, I think it would be an interesting exploration to see how Scala solves same problems using language constructs.

Singleton Pattern

The Singleton pattern describes a way to ensure that only one instance of an object exists.

Scala provides a language construct, the object keyword, to achieve that.

1
2
3
object SantaClaus {
  // there's only one Santa
}

Strategy pattern

The strategy pattern describes a way to select algorithms behavior at runtime.

In Java, a typical way to implement this would be to use classes to encapsulate algorithms.

Scala treats functions as first class citizens, so they can be passed as parameters themselves.

1
2
3
4
5
6
7
8
9
10
type Average = Seq[Int] => Int
class Metrics (values: Int*)  {
  def compute (fn: Average)  = fn (values)
}

def arithmeticMean(values: Seq[Int]) = values.sum / values.size
def harmonicMean(values: Seq[Int]) = values.size / (values reduce (_ + 1/_))

new Metrics(1,2,3).compute (arithmeticMean)
new Metrics(1,2,3).compute (harmonicMean)

Visitor pattern

The purpose of the visitor pattern is to separate the algorithm from the structure it operates on.

For most purposes, in Scala this can be implemented using case classes and pattern matching.

1
2
3
4
5
6
7
8
9
10
sealed trait Read
case class Magazine (title:String, editor: String) extends Read
case class Book (author: String, publisher: String) extends Read
case class Blog (author: String) extends Read

def contactPerson (read: Read) = read match {
  case Magazine(_, editor) => editor
  case Book(author, _) => author
  case Blog(author) => author
}

Template method pattern

The template method pattern defines the main skeleton of an algorithm, allowing parts to be specified or redefined, ensuring that the overarching algorithm is still followed.

This can be implemented in Scala using partially applied functions.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
trait Closeable {
  def close()
}

def using (resource: Closeable)(block: => Unit) {
  try {
      block
    } finally {
      resource.close()
  }
}

val inputStream = new FileInputStream(/*…*/)
using(inputStream) {
  // do something with the input stream
  // but don't worry about closing it
}

Command pattern

The command pattern describes a way to encapsulate in an object all the information needed to call a method at a later time.

Scala’s closures can be used as lightweight command objects.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class RemoteControl {
  def execute(command: => Unit) {
    command
  }
}

object Example {
  val mediaPlayer = new MediaPlayer
  val remote = new RemoteControl

  def playCmd = mediaPlayer.play()
  def pauseCmd = mediaPlayer.pause()

  remote.execute(playCmd)
  remote.execute(pauseCmd)
  remote.execute({
    mediaPlayer.stop()
  }) // inline
}

That’s it for now. Hope you enjoyed it. To be distilled and maybe continued.