Scala’s Singleton Objects are powerful
Scala provides the support for singletons by introducing object, which provides the anonymous type definition and its instantiation. The same instance is used throughout the life of application. This is different from the Gang of four’s singleton implementation that we are so used to. I have found there are various useful features which spawn from this great ability to create object.
Defining Singleton Hierarchies
As we have just discussed, Object are introduced to define singletons but we can also use them to introduce singleton hierarchies. In these hierarchies an Object would contain other Object (s) in a hierarchical fashion. We don’t need to define a corresponding type with container hierarchies.
Here we are just defining Key/ value pairs but scala’s singleton object allows us to further classify the key / value pairs. This is easier to maintain.
We also would be saved from the huge pain of long intellisense scroller as we hit dot on the key / value container. Here we are just trying to use MemberType, just notice how clean the intellisence looks. Isn’t it amazing?
Scala has an amazing support of importing the members of Singleton. Just import everything from it and we can use all fields and member functions defined in the singleton without any name qualifier. They just appear as local functions, which they certainly are not. Here we have imported the members of MemberType. You can notice that we are using fullTime as it is defined locally.
There is another way to do this. You don’t have to directly use an object. We can also use Selfless trait pattern. The pattern allows a companion object of a trait which has the same name as the trait.
Since Scala allows to import the members of an object, we can simply import the object. While writing the unit test, this can be specially useful.
Defining Utility methods
As we discussed above, when we import an object, all of its members are statically imported and we can use them directly. We can use this feature to define helper utility methods in objects and then import the object. Alternatively with Selfless trait pattern, we can define a trait and a companions object (i.e. same name). In any case, we need to import the object to have access to its members.
Now we can import the object members and use them as if they are local members. Here we are importing the members of HelperMethods object. Look how easily we are using greetings method without any preceding type / object name.
Debugging the code clearly shows that the method returns the message to greet a customer.
Tuple with named members
Tuples are specially useful when when we have to return more than one values from a method. But the fields in tuple are not named. Scala also supports tuple but the individual fields are still not named but underscored field indices values. So we end up with _1, _2,… in our code, which is not very readable. This also results in maintenance nightmare of our code base.
Object helps us here to solve this problem too. We can directly return an Object with named fields.
Although we don’t need to define the return type of the function; thanks to implicit type inference in scala. But since scala supports structural typing, we can do it if need be. An example case is to define a trait with structural type as return type of an overridable method.