PEAT Online Course -
Test-Driven Development
using Kotlin

£29.99
  • Theory 'n' practice
  • Test-driven method
  • Acceptance criteria
  • Learn to code mastery
  • Ace that job interview
  • Free updates
PREVIEW

Cake Pattern, Self Types and Realistic Example

09 April 2014 Comments off

2 minutes

407

Original drafted 17 March 2014 for an incomplete article.

The Cake pattern for Scala using a flaming cake as well.

This is the quasi-production code:

package uk.co.xenonique.learning.cake

/**
 * The type Cake
 *
 * @author Peter Pilgrim
 */
class Cake(val name: String) {
  def inspect(): String = {
    name
  }
}

trait Oven {
  def powerUp(): Unit
  def powerDown(): Unit

}
trait CakeMaker {
  def bake( cake: Cake )
}

trait CakeFactory {
  def produce( cakes: List[Cake] )
}

class CakeFactoryImpl extends CakeFactory {
  this: CakeMaker with Oven =>
  override def produce( cakes: List[Cake] ): Unit = {
    powerUp()
    for ( c <- cakes) {
      bake(c)
    }
    powerDown()
  }
}

This is the learning test code:

package uk.co.xenonique.learning.cake

import org.scalatest.WordSpec
import org.scalatest.matchers.MustMatchers
import org.scalatest.mock.MockitoSugar
/**
 * The type CakeSpec
 *
 * @author Peter Pilgrim
 */
class CakeSpec extends WordSpec with MockitoSugar with MustMatchers {

  trait Baker extends CakeMaker {
    override def bake(cake: Cake): Unit = {
      println(s"I'm a baker, baking a cake: "+cake.inspect())
    }
  }

  trait IndustrialOven extends Oven {
    override def powerUp() = {
      println("firing up the oven")
    }
    override def powerDown() = {
      println("venting the oven")
    }
  }

  "Cake" should {
    "understand the cake pattern" in {
      val factory = new CakeFactoryImpl() with Baker with IndustrialOven {
      }
      val cakes = List( new Cake("Battenburg"), new Cake("Cherry Madeira"), new Cake("Lemon and Lime"))
      factory.produce(cakes)
    }
  }
}

Assuming that you know what you are doing: insert this code into a test Scala project with a decent IDE. Run the test should demonstrate the results.

What is the benefit of this so-called Cake Pattern? Well in short, Scala allows self-type with multiple traits (the dependencies). See the definition of CakeFactoryImpl, which expresses a dependency on the type CakeMaker and an Oven traits being mixed-in to the final concrete class. In other words, the final CakeFactoryImpl is a type of CakeMaker (Baker) and also it is type of Oven (IndustrialOven). Therefore, it is a small exercise to write mock objects with these traits, hence the reason I demonstrated with the pattern using a ScalaTest. In fact, it is an exercise to the reader, to write Mockito mocks of this CakeFactoryImpl. Imagine if your Oven was a reference, wrapper or connection pool to a database.

Finally, to understand the cake pattern you have to comprehend the Scala self-types and annotations. Personally, I found this pattern a little convoluted, because of the traits tend to have partial implementations in a production work.

Hey all! Thanks for visiting. I provide fringe benefits to interested readers: checkout consultancy, training or mentorship Please make enquiries by email or
call +44 (0)7397 067 658.

Due to the Off-Payroll Working plan for the UK government, I am enforcing stricter measures on contracts. All potential public sector GOV.UK contracts engagements must be approved by QDOS and/or SJD Accounting. Please enquire for further information.