Stackable Modifications using Traits in Scala

In one of my previous post about Traits in Scala, I have pointed out one sentence that abstract classes and traits in Scala are Stackable. So what does that mean? Let me elaborate a bit on that part.Scala allows stackable modifications to any methods using classes and/or traits which means you can choose very specific behaviour by stacking classes and traits by mixing them together. When you stack new trait by overriding the same method over and over, you will get different or add-on behaviour to your method.

Let’s understand the same concept by a quite simple example.

We have a abstract class Pizza with two abstract methods price() and description() it is extended by its subclass VegDelightPizza, not the price and description of this Pizza is fixed but as a customer you can add new extra toppings, cheese as well as sauce. As you add extra things your price and description will change. So Let’s design our classes using stackable modifications.

object StackableModifications {
    //Base Abstract Class Pizza
    abstract class Pizza {
        def price(): Double
        def description(): String
    }

    //We also have a class VegDelightPizza
    class VegDelightPizza extends Pizza {
        override def price(): Double = 10.0
        override def description(): String = "Veg Delight Pizza"
        def printDesc() = println (description)
        def printPrice() = println ("Price : $" + price)
    }

    //Our restricted traits for extra
    //Trait for adding Extra Mozzarella Cheese
    trait ExtraMozzarellaCheese extends VegDelightPizza{
        override def price():Double = super.price + 0.50
        override def description():String = super.description + "\n + Extra Mozzarella Cheese"
    }

    //Trait for adding Extra Tomato Toppings
    trait ExtraTomatoToppings extends VegDelightPizza{
        override def price():Double = super.price + 0.75
        override def description():String = super.description + "\n + Extra Tomato Toppings"
    }

    //Trait for adding Extra Black Olives
    trait ExtraBlackOlives extends VegDelightPizza{
        override def price():Double = super.price + 0.15
        override def description():String = super.description + "\n + Extra Black Olives"
    }
    
    def main(args:Array[String]){
        println ("Our First Pizza")
        
        //This is how you implement stackable traits
        var pizza1 = (new VegDelightPizza 
                                with ExtraMozzarellaCheese 
                                with ExtraBlackOlives)
        
        pizza1.printDesc
        pizza1.printPrice
        println ("")
        println ("Our Second Pizza")
        
        //Another implementation of stackable traits
        var pizza2 = (new VegDelightPizza 
                                with ExtraMozzarellaCheese 
                                with ExtraBlackOlives 
                                with ExtraTomatoToppings)
        
        pizza2.printDesc
        pizza2.printPrice   
    }
}

Let’s execute above example using scalac and scala commands,

$ scalac StackableModifications.scala
$ scala StackableModifications

//Output:
// Our First Pizza
// Veg Delight Pizza
//  + Extra Mozzarella Cheese
//  + Extra Black Olives
// Price : $10.65
// 
// Our Second Pizza
// Veg Delight Pizza
//  + Extra Mozzarella Cheese
//  + Extra Black Olives
//  + Extra Tomato Toppings
// Price : $11.4

You can see in output that we can select any combination of traits and can stake them together.

This is same as decorator design pattern with below differences,

  • Decoration done on class level rather object level in decorator design pattern.
  • Stackable traits ExtraMozzarellaCheese, ExtraTomatoToppings and ExtraBlackOlives decorates core class (or trait) VegDelightPizza at compile time, similar thing is being done in decorator pattern at runtime while decorating the objects.

See, it was quite simple…..!!!!! Stay tuned for my upcoming posts on Scala :)

References

http://www.artima.com/scalazine/articles/stackable_trait_pattern.html

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>