What's the idea
Annotations in Java do a great job for developers to keep all information around our code at a single place. And the place where this information is kept is the one which is most natural for us, the source code itself.
Think about how annotations like @Entity,
@Webservice and @Stateful
changed the way developers write source code, having all available at the
source code level what is needed to run the code in our infrastructure and
what we need to know when we read the source code to understand what's
happening when we analyze and debug the code. No more
deployment descriptors and and no much reason for any external source code
documentation.
Composite, and almost every developer knows what is meant.
The rest should really look it up at the GoF book.
And now, time moved on, I hardly remember the problem we solved at that time and
even vaguer are the memories how we did it. The team has changed and what
we had coded then is now in the hands of some guys of another department. And they
keep asking questions, what's happening here at this class, and why is this so complicated,
what's the idea behind this? Ok I can't remember, so lets look at the code again. Ah, this
class here, and that one there, that are the keys. Here, look at this, that's a Command Pattern,
here's the Command, that is the ConcreteCommand and
that one is the Client. The picture's is restored in mind and everything's
easy again.
We should have documented this in the beginning, shouldn't we?
And that's where annotations and the idea that only the source tells the true story in the end come back again. Let's use annotations to make our decisions on code design permament. Have a look at the source code and it spells the design pattern we have put into it.
How does this looks like
Let's say we have some management console which can configure a lot of of stuff in our software. And it has menu links which are disabled when we can not change a feature.
package example;
import org.jpatterns.gof.CommandPattern;
@CommandPattern.Command(comment = "generic interface for all configuration tasks",
undoable = false,
participants = { Client.class, CreateUserCommand.class, DeleteUserCommand.class })
public interface ConfigurationCommand {
boolean canChange(ConfigurationParameters parameters);
Result change(ConfigurationParameters parameters);
}
Pretty nice, it says: this code is the Command interface from the GoF CommandPattern,
our commands can not be undone, and that other participants in this design patterns are the classes
Client, CreateUserCommand, DeleteUserCommand. That's what we need to know.
And when we look at the other classes it looks like this:
import org.jpatterns.gof.CommandPattern;
@CommandPattern.ConcreteCommand(
comment="concrete command implementation",
participants={ConfigurationCommand.class, Client.class})
public class CreateUserCommand implements ConfigurationCommand {
public CreateUserCommand(Receiver receiver) {
this.receiver = receiver;
}
@Override
public boolean canChange(ConfigurationParameters parameters) {
return true;
}
@Override
public Result change(ConfigurationParameters parameters) {
User user = userManager.createUser(parameters);
Result result = new Result(user);
receiver.action(result);
return result;
}
private UserManager userManager;
private Receiver receiver;
}
import org.jpatterns.gof.CommandPattern;
@CommandPattern.Client(comment="react on user creation")
@CommandPattern.Invoker(comment="trigger user creation")
public class Client implements Receiver {
public void action(Result result) {
if (result.isSuccess())
System.out.println("User created: " + result.getObject());
else
System.out.println("User creation failed: " + result.getErrorMessage());
}
public void createUser(ConfigurationParameters parameters) {
ConfigurationCommand command = new CreateUserCommand(receiver);
if (command.canChange(parameters)) {
command.change(parameters);
}
}
private Receiver receiver;
}
import org.jpatterns.gof.FacadePattern;
@FacadePattern(comment="service facade for user management", participants={CreateUserCommand.class})
public interface UserManager {
User createUser(ConfigurationParameters parameters);
User deleteUser(ConfigurationParameters parameters);
}
That tells us pretty much all we wanted to know, even our shortcut to the GoF pattern is here.
We decided that we could put the Invoker and the Client in one class, so there are
two annotations for this class because it servers two roles in the pattern. And the UserManager is a
Facade to the really big and complex user management system.
And looking at the javadoc (in Eclipse just hover over the annotation) we even get some references where to look up all the details of the design pattern.
How to do your own patterns
When your organization has already drafted or documented a set of own patterns, you can easily define them
as annotations as well. Pattern annotations are just interfaces and you should remove any dependencies for the runtime
with @Retention(RetentionPolicy.RUNTIME). And of course you can define
anti-patterns as well. So if you there are some guys in your department who love to do everything from scratch before using
other people's solutions, mark the code with @NotInventedHere :-)
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@DesignPattern(type = Type.ENTERPRISE)
public @interface NotInventedHere {
Class[] participants() default {};
String comment() default "";
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
public @interface Redundancies {
Class[] participants() default {};
String comment() default "";
}
}
References
- JPatterns.org is the home of the annotation based design patterns. They have put the complete GoF and several other design patterns into code already.
- A huge thanks to Heinz Kabutz for promoting this and many other great ideas.
- Here's the source of our example
About the Author
Johannes Beckprofessional record of 12 years in the software industry, especially in enterprise systems and Java
software architect at 1&1 Internet AG
37 years old, living in Karlsruhe, Germany.
Technorati Tags: Java Annotations Design Patterns

I don't know what other may think but this is kind of lame!
Should I say this is "pattern oriented programming"? Patterns are vehicles to achieve maintainability and re-usability. But when I heard someone says "I implemented pattern X here and pattern Y there in this code" I feel like he just gets out of school. I've never heard any programming experts claim they use this pattern and that pattern. Even though, looking at the code we all know they use design pattern. Calling out design pattern should only be applied in school and for beginner. Everyone is welcome to call it out. But experts normally don't :))