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

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.

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.


Learn tips and best practices for optimizing your capacity management strategy with the Market Guide for Capacity Management, 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 }}