Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Cake Pattern, Self Types and Realistic Example

DZone's Guide to

Cake Pattern, Self Types and Realistic Example

· Performance Zone
Free Resource

Transform incident management with machine learning and analytics to help you maintain optimal performance and availability while keeping pace with the growing demands of digital business with this eBook, brought to you in partnership with BMC.

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:

1	package uk.co.xenonique.learning.cake
2	 
3	/**
4	 * The type Cake
5	 *
6	 * @author Peter Pilgrim
7	 */
8	class Cake(val name: String) {
9	  def inspect(): String = {
10	    name
11	  }
12	}
13	 
14	trait Oven {
15	  def powerUp(): Unit
16	  def powerDown(): Unit
17	 
18	}
19	trait CakeMaker {
20	  def bake( cake: Cake )
21	}
22	 
23	trait CakeFactory {
24	  def produce( cakes: List[Cake] )
25	}
26	 
27	class CakeFactoryImpl extends CakeFactory {
28	  this: CakeMaker with Oven =>
29	  override def produce( cakes: List[Cake] ): Unit = {
30	    powerUp()
31	    for ( c <- cakes) {
32	      bake(c)
33	    }
34	    powerDown()
35	  }
36	}

 This is the learning test code:

1	package uk.co.xenonique.learning.cake
2	 
3	import org.scalatest.WordSpec
4	import org.scalatest.matchers.MustMatchers
5	import org.scalatest.mock.MockitoSugar
6	/**
7	 * The type CakeSpec
8	 *
9	 * @author Peter Pilgrim
10	 */
11	class CakeSpec extends WordSpec with MockitoSugar with MustMatchers {
12	 
13	  trait Baker extends CakeMaker {
14	    override def bake(cake: Cake): Unit = {
15	      println(s"I'm a baker, baking a cake: "+cake.inspect())
16	    }
17	  }
18	 
19	  trait IndustrialOven extends Oven {
20	    override def powerUp() = {
21	      println("firing up the oven")
22	    }
23	    override def powerDown() = {
24	      println("venting the oven")
25	    }
26	  }
27	 
28	  "Cake" should {
29	    "understand the cake pattern" in {
30	      val factory = new CakeFactoryImpl() with Baker with IndustrialOven {
31	      }
32	      val cakes = List( new Cake("Battenburg"), new Cake("Cherry Madeira"), new Cake("Lemon and Lime"))
33	      factory.produce(cakes)
34	    }
35	  }
36	}

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.


Evolve your approach to Application Performance Monitoring by adopting five best practices that are outlined and explored in this e-book, brought to you in partnership with BMC.

Topics:

Published at DZone with permission of Peter Pilgrim, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}