Monday, 7 January 2013

Cake Pattern in JDK8 – Evolve beyond dependency injection

Spring has recently released support for Scala (see introducing-spring-scala). This of course can't go unheeded and there is only one correct way to counter this: Outlining the Cake Pattern for Java ;-)

In order to create unnecessary confusion I try to illustrate the principles by implementing an extremely simple cake database with web frontend. You'll find the repository for this at: https://github.com/thoraage/cake-db-jdk8

In order to use the code in this project now (7. January 2013) you will need to download the lambda version of JDK8. You'll find it here: http://jdk8.java.net/lambda/

What is the Cake Pattern?

The Cake Pattern is dependency injection's type safe and annotation/xml-free cousin. It works by creating traits for each module. Traits in Scala are basically interfaces with state and methods. These traits can be layered on top of each other into a concrete class or object; a cake. You can combine these modules in any way you'd like to create different cakes according to different demands.

Why?

Java developers have been toiling away writing XML-files and flimsy annotations for years. It's time that they get a taste of the goodness that static typing were supposed to give them.

How?

JDK8 includes among other handsome features something called virtual extension methods. This opens for adding code into interfaces. If you know Scala you can think of it as Scala's traits on sedatives. However, since you can add as many interfaces as you like you now have a limited multiple inheritance. Here is an example of how such an interface might look:

public interface AnInterface {
    default void sayHello() {
        System.out.println("Hello");
    }
}

Problem with State

Since you still can't have state in interfaces I've implemented that through the SingletonModule interface and the SingletonModuleImpl class. This is not optimal as the class will devour our potential "real" inheritance. However, I've not found any competing use for it; yet. The SingletonModule looks like this:

public interface SingletonModule {
    interface Singleton {
        <M extends SingletonModule, T> T get(Class<M> clazz);
        <M extends SingletonModule, T> void put(Class<M> clazz, T t);
    }
    void initialize();
    Singleton getSingleton();
}

I've created an initialisation step here so that I don't have to worry about thread safety of lazy singletons. It also asserts fast failure. You can see how we put and get singletons in the CakeJdbcDbModule:

public interface CakeJdbcDbModule extends DbModule, DbConfigurationModule, SingletonModule {
    class JdbcDb implements Db {
        ...
    }
    @Override
    default void initialize() {
        getSingleton().put(CakeJdbcDbModule.class, new JdbcDb(this));
    }
    @Override
    default Db getDb() {
        return getSingleton().get(CakeJdbcDbModule.class);
    }
}

Sadly the initialisation methods will have to be initialised from the top for each module with initialisation needs.

The Stack

If we start from the top it looks like this:

class CakeStack extends SingletonModuleImpl implements CakeConfigurationModule, CakeJdbcDbModule, CakePageHandlerModule, JettyWebHandlerModule {
    @Override
    public void initialize() {
        CakeJdbcDbModule.super.initialize();
        JettyWebHandlerModule.super.initialize();
    }
}

This represent a complete runnable stack. Here you can also observe the initialisation in action. Let us concentrate on the most important modules:

  • CakeConfigurationModule - Contains configuration parameters
  • CakeJdbcDbModule - Provides access to the database
  • CakePageHandlerModule - Handles page requests
  • JettyWebHandlerModule - Starts a web server and directs requests to the page handler

All these modules have to be added in the order of their dependencies. JettyWebHandlerModule last since it depends on CakePageHandlerModule and CakeConfigurationModule. CakeConfigurationModule first as it is not dependent on anything.

To start using this stack we need only instantiate it and start the WebHandler:

new CakeStack().getWebHandler().start();

The CakeStack refer only concrete implementations of all the modules we need and we could change easily exchange the implementations when needed. For example by inserting a CakeMongoDbModule instead of the CakeJdbcDbModule. This will in no way affect how the CakePageHandlerModule get cakes from the database by calling 'module.getDb().getCakes()'.

Creating a Module

Each module is implementing a method that return the needed module implementation. Default methods on the interfaces enable us to add as many modules as we please. Each module on the other hand is implemented as generic as possible:

public interface CakePageHandlerModule extends PageHandlerModule, DbModule {
    class CakePageHandler implements PageHandler {
        ...
    }
    @Override
    default PageHandler getPageHandler() {
        return new CakePageHandler(this);
    }
}

In this example we extend the PageHandlerModule and the DbModule. The PageHandlerModule is the responsibility of this module so we implement that. The DbModule however, we just request and leave for someone else to provide an implementation for us. This makes it simple to have one implementation for test and a completely different for production.

I have modelled CakePageHandler as a nested class of the CakePageHandlerModule-interface. Notice however that I need to pass the module in as a constructor argument. A nested class B in a class A will have access to A through 'A.this'. A nested class in an interface on the other hand is more akin to a static nested class and does not really have a relation to its outer class. In order to underline the connection between the entities I've chosen to keep the module implementation inside the module interface anyway.

Conclusion

All-in-all I'm quite happy about how this experiment unfolded. It has some drawbacks compared to applying it in Scala. Particularly the way Scala traits hold state and how nested classes in traits can directly access the trait. That aside, I believe it presents a compelling way to build an application and it would be really interesting to see how this would play out in a real project.

Tuesday, 4 September 2012

Deverbosing ScalaQuery session handling

Just started on a small project employing ScalaQuery and Unfiltered. They are great toolkits, but one thing have been bothering me about ScalaQuery. The typesafe handling of the sessions can make the code a little verbose.

Here's an example of the code before I started my refactorings:



The code receive a json-message through a http put operation on the path http://host/rest/products. It is read to the case class Product and we insert into into the database and returns a json-representation of the save Product.

My problem today starts at the ProductDb.database withSession in line 9. We bind the session implicitly in order to use it in the insertValue and the Query(...).where(...).list statements. The session parameter and implicit declaration in itself is two lines. Of course I could have explicitly specified the session at the insertValue and list method calls, but I kind of like the way it's hidden. When I've got lots of these cases the lack of DRY-ness really creeps out. I just want to hide the session handling completely.

Here is the code I want:



Now this looks a tad better. There are still issues, but the noise of the ScalaQuery session is completely gone. Since I have more of these match cases my code has been reduced substantially. Of course it doesn't work yet. The insertValue and the list methods both demands their implicit session.

Originally I tried to find a way to make it available by extending PartialFunction, but I found no way to make that work; maybe it's not possible. Instead I chose to extend the StorageService with a new trait ScalaQuerySession:



The trait make the session implicitly available for the ScalaQuery methods. Of course we need to  acquire the session before the StorageService-implementation is called and return it on the end.

We do this by implementing the intent method in a new trait ThreadMountedScalaQuerySession and make it call the StorageService intent method on the super object:
 

By binding the session variable to a DynamicVariable I guarantee that it will be separate for each thread in the pool that passes through the intent method.

Now we need only create the object StorageService like this to make it play:

new StorageService with ThreadMountedScalaQuerySession

Thursday, 14 April 2011

Playing with Scala Dynamic

The news spread fast through twitter when the Scala dynamic trait was checked into the Scala repository some months ago. It's now in the 2.9RC1 version that arrived just the other day. So I wondered about what to use something like that for. It was intended for inline communication with dynamic languages like Ruby and Python, but I decided to try to mimic Ruby-on-Rails table inheritance.

For this I needed Scala 2.9RC1 (http://www.scala-lang.org/downloads) and apparently the '-Xexperimental' command line argument. My scala command line for experimenting look like this:

# scala-2.9.0.RC1/bin/scala -Xexperimental -classpath ~/.ivy2/cache/com.h2d/h2/jars/h2-1.2.138.jar

For simplicity I used a h2-database and set it up like this:



Then of course we have my Dynamic trait which implement the 'applyDynamic(...)(...)' method. This is similar to Rubys missing method; it simply looks through the map of data that it got to see if the method you called exist. So far only data access is supported:



Of course we need to have a companion object to do the data retrieval. It will only support one method 'findAll':



Then we can go on to create the important classes to represent the table:



So then will this fly? If so I should be allowed to access the data through methods I haven't written:



Some thoughts:

Constantly having to cast return values destroys some of the fun. Also, I dislike the idea of these fields spreading the dynamic plague all over my code. An even more unsettling thought is what this does to the line between static goodness and dynamic ficklety. We know when we see a text in "quotes" that this is where the compiler draw the line and takes no responsibility. With the dynamic trait however we don't know whether 'obj.NAME' really exists. I guess this is a little like sex ed in school; now that you know how it's done. Don't do it ;-)

Thursday, 20 September 2007

Mac + Mozilla = clutterville population you

Tired of the way Thunderbird and Firefox clutter the desktop of your Mac. I certainly was. Each and every file I opened was left on the desktop until I could no longer separate the important files from the thrash. So I tried to search for a solution.

I found it in a two year old bug report (some bug report). Seems like Mozilla only uses the Mac OS X standard user temporary directory; which is the desktop. So; how to fix it. Simply open Safari and open the configuration and change the download directory under the general tab. So easy; so far fetched :-)

If you don't like this fix you could choose another route by telling Firefox to delete downloaded temporary files on exit. I don't know if the same can be done for Thunderbird. I chose the first solution because I often find myself editing opened documents forgetting that I opened them in Firefox; and I don't want to loose the changes. Nevertheless; this comment shows how: some bug report comment.

Friday, 31 August 2007

Maven2 classpaths printout

Ever needed to find the classpaths your maven2-project uses? Add this to build-plugins of your pom and run mvn antrun:run:

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<configuration>
<tasks>
<property name="compile_classpath" refid="maven.compile.classpath"/>
<property name="runtime_classpath" refid="maven.runtime.classpath"/>
<property name="test_classpath" refid="maven.test.classpath"/>
<property name="plugin_classpath" refid="maven.plugin.classpath"/>

<echo message="compile classpath: ${compile_classpath}"/>
<echo message="runtime classpath: ${runtime_classpath}"/>
<echo message="test classpath: ${test_classpath}"/>
<echo message="plugin classpath: ${plugin_classpath}"/>
</tasks>
</configuration>
</plugin>