Stackable Traits
— Scala — 1 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 easy34 trait Init {5 def init6 }78 class CoreInit extends Init {9 def init = println("end of stackable trait")10 }1112 trait UserStorage extends Init {13 abstract override def init() {14 println("create table if not exist users....")15 super.init16 }17 }1819 trait ItemsStorage extends Init {20 abstract override def init() {21 println("create table if not exist items ....")22 super.init23 }24 }2526 trait SimilarItemsStorage extends Init {27 abstract override def init() {28 println("create table if not exist similaritems ....")29 super.init30 }31 }3233 class CassandraStorage(domain: String)34 extends CoreInit35 with SimilarItemsStorage36 with UserStorage37 with ItemsStorage3839 val storage = new CassandraStorage("acme")4041 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 trait45}
sdf