Skip to content

peter siemen, dipl.-inf.

Stackable Traits

Scala1 min read

For the Scala project I am currently working on I needed to come up with a structured initialization process of my datamodel. When a customer creates her domain I need to set up a number of cassandra tables/keyspaces that will hold her data. Let’s say that each customer’s domain will need 3 cassandra tables: Users, Items and SimilarItems. These three tables should be grouped somewhere. So let’s put them into a domain class that I call CassandraStorage(domain:String).

To not forget to initialize each table I want to have a trait Init with an init method that each table must implement. Finally when all tables are gathered within the CassandraStorage object, I need to make sure that the init method of every table trait is called.

I find that Stackable Traits fit the bill pretty nicely. I define one class CoreInit that serves as an "end marker" of my cascading calls of init methods. The CassandraStorage class extends the CoreInit, so that I can invoke init on it and to have the "end marker" in the right place after class linearization. All table traits get then mixed into the CassandraStorage class. In order to stack the invokation of all table trait’s init methods, each table trait implementation of init needs to invoke super.init in the end. This just passes the execution one step higher in the linearized class hierarchy and finally ends up at my "end marker" init method of CoreInit.

1object stackable {
2 println("Stackable Traits are easy") //> Stackable Traits are easy
3
4 trait Init {
5 def init
6 }
7
8 class CoreInit extends Init {
9 def init = println("end of stackable trait")
10 }
11
12 trait UserStorage extends Init {
13 abstract override def init() {
14 println("create table if not exist users....")
15 super.init
16 }
17 }
18
19 trait ItemsStorage extends Init {
20 abstract override def init() {
21 println("create table if not exist items ....")
22 super.init
23 }
24 }
25
26 trait SimilarItemsStorage extends Init {
27 abstract override def init() {
28 println("create table if not exist similaritems ....")
29 super.init
30 }
31 }
32
33 class CassandraStorage(domain: String)
34 extends CoreInit
35 with SimilarItemsStorage
36 with UserStorage
37 with ItemsStorage
38
39 val storage = new CassandraStorage("acme")
40
41 storage.init //> create table if not exist items ....
42 //| create table if not exist users....
43 //| create table if not exist similaritems ....
44 //| end of stackable trait
45}

sdf

© 2020 by peter siemen, dipl.-inf.. All rights reserved.