{"id":1554,"date":"2014-04-09T12:17:18","date_gmt":"2014-04-09T11:17:18","guid":{"rendered":"http:\/\/www.xenonique.co.uk\/blog\/?p=1554"},"modified":"2014-04-09T12:17:18","modified_gmt":"2014-04-09T11:17:18","slug":"cake-pattern-self-types-and-realistic-example","status":"publish","type":"post","link":"https:\/\/www.xenonique.co.uk\/blog\/2014\/04\/09\/cake-pattern-self-types-and-realistic-example\/","title":{"rendered":"Cake Pattern, Self Types and Realistic Example"},"content":{"rendered":"<p>Original drafted 17 March 2014 for an incomplete article. <\/p>\n<p>The Cake pattern for Scala using a flaming cake as well. <\/p>\n<p>This is the quasi-production code:<\/p>\n<pre class=\"brush: scala; title: ; notranslate\" title=\"\">\r\npackage uk.co.xenonique.learning.cake\r\n\r\n\/**\r\n * The type Cake\r\n *\r\n * @author Peter Pilgrim\r\n *\/\r\nclass Cake(val name: String) {\r\n  def inspect(): String = {\r\n    name\r\n  }\r\n}\r\n\r\ntrait Oven {\r\n  def powerUp(): Unit\r\n  def powerDown(): Unit\r\n\r\n}\r\ntrait CakeMaker {\r\n  def bake( cake: Cake )\r\n}\r\n\r\ntrait CakeFactory {\r\n  def produce( cakes: List[Cake] )\r\n}\r\n\r\nclass CakeFactoryImpl extends CakeFactory {\r\n  this: CakeMaker with Oven =&gt;\r\n  override def produce( cakes: List[Cake] ): Unit = {\r\n    powerUp()\r\n    for ( c &lt;- cakes) {\r\n      bake(c)\r\n    }\r\n    powerDown()\r\n  }\r\n}\r\n<\/pre>\n<p>This is the learning test code:<\/p>\n<pre class=\"brush: scala; title: ; notranslate\" title=\"\">\r\npackage uk.co.xenonique.learning.cake\r\n\r\nimport org.scalatest.WordSpec\r\nimport org.scalatest.matchers.MustMatchers\r\nimport org.scalatest.mock.MockitoSugar\r\n\/**\r\n * The type CakeSpec\r\n *\r\n * @author Peter Pilgrim\r\n *\/\r\nclass CakeSpec extends WordSpec with MockitoSugar with MustMatchers {\r\n\r\n  trait Baker extends CakeMaker {\r\n    override def bake(cake: Cake): Unit = {\r\n      println(s&quot;I'm a baker, baking a cake: &quot;+cake.inspect())\r\n    }\r\n  }\r\n\r\n  trait IndustrialOven extends Oven {\r\n    override def powerUp() = {\r\n      println(&quot;firing up the oven&quot;)\r\n    }\r\n    override def powerDown() = {\r\n      println(&quot;venting the oven&quot;)\r\n    }\r\n  }\r\n\r\n  &quot;Cake&quot; should {\r\n    &quot;understand the cake pattern&quot; in {\r\n      val factory = new CakeFactoryImpl() with Baker with IndustrialOven {\r\n      }\r\n      val cakes = List( new Cake(&quot;Battenburg&quot;), new Cake(&quot;Cherry Madeira&quot;), new Cake(&quot;Lemon and Lime&quot;))\r\n      factory.produce(cakes)\r\n    }\r\n  }\r\n}\r\n<\/pre>\n<p>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.<\/p>\n<p>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 <code>CakeFactoryImpl<\/code>, 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 <code>CakeFactoryImpl<\/code> is a type of <code>CakeMaker<\/code> (<code>Baker<\/code>) and also it is type of <code>Oven<\/code> (<code>IndustrialOven<\/code>). 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.<\/p>\n<p>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. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>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: This is the learning test code: Assuming that you know what you are doing: insert this code into a test Scala project with a decent IDE. Run the test should [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[123,75,172,40,6,52],"tags":[],"_links":{"self":[{"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/posts\/1554"}],"collection":[{"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/comments?post=1554"}],"version-history":[{"count":3,"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/posts\/1554\/revisions"}],"predecessor-version":[{"id":1573,"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/posts\/1554\/revisions\/1573"}],"wp:attachment":[{"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/media?parent=1554"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/categories?post=1554"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.xenonique.co.uk\/blog\/wp-json\/wp\/v2\/tags?post=1554"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}