Donnerstag, 29. November 2007

Martin Fowler on Domain Specific Languages

Recently I was on Martin Fowler's site and lerned about his new - yet to be written- book about DSLs. One or two days later I found this video on InfoQ where he's giving an introduction to DSLs and is showing how the DSL representation can be intern or extern.

For his book I hope he is going really deep into the possibilities of definig DSLs with closures. I've seen some impressive builders composed with closures by the Grails folks. I'm not really sure, but closures seem a lot more powerful, easier to use and clearer to read when it comes to intern Domain Specific Languages then Java5 methods are.

But in the end of the day it all boils down to how powerful your DSL should be and what the best syntax for it is whether you use an intern language, XML or simple representation.

Update: Just today I read this post by Stephan who links to a some other blog postings related to DSLs. He tried to rewrite the Grails HTML Markup Builder in Java. And he seems to share my opinion about closures enabling more powerful DSLs.

Dienstag, 27. November 2007

Using Enums as Proxies/Decorators in Java - forget about switch

Every Java developer knows that you have enums in Java since Java 5.0.

Enums are cool. Especially the ability of getting the right instance of an enum-class by calling the static valueOf()-method with the respective name string makes enums a nice choice in configurations.

In this example I'm using an enum to determine the style of notification for an event or user.


public enum NotificationType {
NO_NOTIFICATION,
EMAIL;
}


While NotificationCommand is a simple interface with implementations like DoNothingCommand, EmailNotificationCommand and SmsNotificationCommand:


public interface NotificationCommand {
void execute(NotificationCmdReceiver rec);
}


Like I said, we want to determine the type of notification by the NotificationType enum.

Most people use enums in switch-statements like this:


public void notify(
NotificationType type,
NotificationCmdReceiver rec) {

NotificationCommand cmd;

switch (type) {
case EMAIL:
cmd = new EMailCommand();
break; // DO NOT FORGET THIS BREAK OR IT WILL BREAK YOUR NECK
case NO_NOTIFICATION:
default:
cmd = new DoNothingCommand();
break;
}

cmd.execute(rec);
}



I myself hate switch/case statements and I think switch/case/break is not OOP-style.
Everytime I use this kind of statement I make mistakes. Often I forget to test some of the several paths of execution, sometimes I forget a break, sometimes I forget the default case and so on.

One problem in particular is refactoring switch-break-statements from or to a version where you use (multiple) returns inside the switch. NEVER DO THIS WITHOUT GOOD UNIT-TESTS!!! (I write from experience...)


So this would be a better version because it eliminates the switch statement.


public enum NotificationType {

NO_NOTIFICATION(new DoNothingCommand()),
EMAIL(new EMailCommand());

NotificationCommand command;

private NotificationType(NotificationCommand command) {
this.command = command;
}

public NotificationCommand getCommand() {
return command;
}
}


You must be aware, that this version does not recreate a new Command-Object for every call. If you want to do so, you have to write something like this:


public enum NotificationType {

NO_NOTIFICATION{
public NotificationCommand getCommand() {
return new DoNothingCommand();
}
},
EMAIL{
public NotificationCommand getCommand() {
return new EMailCommand();
}
};


public abstract NotificationCommand getCommand();
}


In both cases the notify()-method looks like this:


public void notify(
NotificationType type,
NotificationCmdReceiver rec) {

NotificationCommand cmd = type.getCommand();

cmd.execute(rec);
}


Much more simpler, isn't it? (Update: Okay, I have to admit that it actually does not look simpler. But thats because this example simplifies the logic in the different switch-cases a lot. In real world projects there will be more than 2 different enum values (which means more breaks) and there are more lines for each case. Using this technique lets you break up this one method into some smaller ones. To my mind it's much easier to test n different methods with one execution path each than to test one method with n different execution paths.)

But you can do even more simpler. While it is true that all emums in Java inherit from java.lang.Enum and can't extend any other class, developers seem to forget that enums can implement interfaces:


public enum NotificationType
implements NotificationCommand {

NO_NOTIFICATION{
public NotificationCommand getCommand() {
return new DoNothingCommand();
}
},
EMAIL{
public NotificationCommand getCommand() {
return new EMailCommand();
}
};


public abstract NotificationCommand getCommand();

public void execute(NotificationCmdReceiver rec) {
getCommand().execute(rec);
}
}

The enum NotificationType is now something like a decorator / proxy for NotificationCommands. And the notify()-method boils down to only one line:


public void notify(
NotificationType type,
NotificationCmdReceiver rec) {

type.execute(rec);
}


And now you see much clearer that this method could be static. To my mind, often static methods are a signal of poor design and should be refactored. You can inline the last line and remove the notify()-method.

Update: I want to stress that this post actually is more about that enums are able to implement interfaces and it can be useful to do so than it is about not using switch. In fact even if you let your enums implement interfaces you still can use them with switch. But additionally you get all the advantages that comes with it, especially to use your enum transparently.

Mittwoch, 21. November 2007

Message Routing with Apache Camel

When I was in Munich for WJax (see my previous post) I was talking to some people about my current project at my dayjob. We are building a big distributed system for logistics where you have several warehouses, distributors and suppliers. We use ActiveMQ and ServiceMix to let the different applications talk to each other. So message routing is something we need to have but is only partially implemented in our system.

The people I talked to recommended to check out Apache Camel for message routing. So did I and was really impressed. Camel uses an internal DSL for configuration which is very simple and intuitive. The Camel developers even show how to implement most of the Enterprise Integration Patterns in the Camel wiki. On top of that Camel has implemented support for a lot of components.

Freitag, 9. November 2007

My WJax Review

I just came back from W-Jax/SOACON yesterday where I've seen a lot of great talks. Three days of high quality input can really make you feel your synapses growing in your brain.

I learned a lot of things while staying in Munich. MVS (Most Valuable Speaker) for me was Gregor Hohpe who is a really cool guy. He is co-author of one of my favorite books (Patterns of EAI) and I was really excited to meet him in person.

He was the first one who made clear to me what SOA is really all about, something that all these SOA hype business people never were able to. You don't know how annoying these people are. These people make you feel like a second class citizen if you don't have WS-* everywhere and use some BPEL and BPM and BLA BLA BLA.

But thanks to Gregor, now I know that we are on the right track. More than that I know we can reach leading position if we abstract a little bit more here and do some looser coupling there, etc. Nothing to difficult, nothing to worry about, just utilizing more patterns and make things work.
I had a very nice discussion with Gregor and almost missed my flight from Munich back to Berlin.

Gregor Hohpe also was the one who encouraged the audience to write more blogs and articles about patterns and related topics. And this is exactly what I'm trying to do right now. ;-)

But I learned a lot more things on W-Jax. I attended some talks about OSGi which soon will be featured in every serious Java project. I swear. In 2009 you won't see any bigger Java project (open source or not) which isn't OSGi-enabled. I bet Peter Kriens would tell you the same.

And I attended some talks about the Java language, Groovy and Spring.

These guys from interface21 seem to be really busy these days. They just released Spring 2.5 and are working hard on Spring Webflow 2.0 and Spring Batch. I'm thinking about using Webflow as lifecycle controller in my project. As far as I know do they try to utilise Spring Webflow to manage the JSF lifecycle.

Groovy lead Dierk König showed off some really cool Groovy stuff. I have to admit I bought 3 books on Groovy & Grails and 2 Spring books approx one year ago and never had time to do more than a little Grails demo. Shame on me. I promise I will do more with Groovy. Hopefully my team leader at my dayjob will allow me to use it.

Angelika Langer showed some cool stuff she did with Java annotations. I use annotations on my project too, but it's astonishing what different things you are able to do with them at compile time and runtime. Someone should really write a book about annotation patterns.

By the way, does anybody know a good book about AOP patterns? Runtime annotation analysation with reflection seems to be a lot like AOP to me and I want to know more about that.

Powered By Blogger