Saturday, July 2, 2005

Annotation use cases

My first blog here but will cut straight to the point.

The most talked about feature at J1 this year was annotations. It was as if every new API / framework had to have support for annotations or must have something pertaining to it on their radar to gain acceptance or even be considered a contender.

I have not yet being able to make my mind if this profileration of @YeahIHaveAnAnnotationToo is a good thing or not. For the time being I am trying to come up with use cases of where annotations make sense. Here are some that I have assimilated from various blogs, J1 sessions and my own brain dumps:

1. Dependency injection.

  • The @Resource and the @EJB annotations introduced by EJB3 are obvious examples of dependency injections. Any custom framework will have some notion of a context or an environment or a manager and injecting such resources into users' classes would make a lot of sense.

2. Aspects (boiler plate stuff handled by the container / framework) and interceptors

  • The @TransactionAttribute annotation associates a transaction aspect to a method. @Query and @Update annotations introduced by JDBC 4.0 perform tasks which go beyond just boiler plate - they actually populate and manipulate objects which directly affect business logic. I've put interceptors alongwith aspects coz I consider interceptors as an implementation technique for aspects (Correct me if I am wrong). I think one needs to be really careful when designing annotations in this category because taking this route could be a slippery slope - you design a bunch of annotations which perform certain core tasks and your co-developer has his/her own set of tasks which s/he religiously believes are "core" and your manager feels that it's critical to design a third set to appease that billion $ client. IMO, for this category of annotations just design those which strictly do boiler plate stuff and don't necessarily alter the business state for the client.

3. Callback methods

  • The @PostActivate and @PrePassivate ones fall in this category. I am not sure if I am a fan of annotations in this category. Basically with this all you are trying to do is eliminate the need to implement certain interfaces. Which means all you gain is that you don't need to have empty implementations for methods that you don't need. But it becomes very difficult for somebody to understand what contracts your object fulfills or which methods are actually designated as callbacks. One might argue that objects are no longer POJOs if they have to adhere to some framework specific interfaces - if this argument is important for you then implement callback listeners (an alternative that EJB3 also provides) to achieve this objective.

4. Container contracts

  • Tagging an EJB as @Stateless and @Stateful makes it known to the container how it should treat that bean. Moreover, it also sets a programming pattern for the user how to access and use these objects. Most marker annotations could be included in this category. So if your framework needs to handle certain objects in specific ways, you could think about such annotations.

5. Programmatic access to metadata for classes, fields and methods.

  • This is an oft forgotten use case but one which I think makes sense for UI objects. While it's a given that it's important to publish information regarding a method or a field's behavior through detailed comments and Javadocs; for UI objects this information may also need to be presented to the user on desktop panels and HTML forms. So the next time you author a UserBean think about associating a runtime @Description annotation with the username and password fields so as to give consistent descriptions for these fields across different views of your app.

(I'll try to add more as I get my head around it more (or if you have any more points for me).)

While this push toward annotated POJOs for everything might be a good thing; the thing that I fear is that Java classes of the future would have less Java code and more of annotations. It may become increasingly difficult for the user to deterministically gauge what behavior any given method would exhibit because what the method does could change dramatically depending on which annotations were applied when the method was actually called.

Not trying to attach a pessimistic annotation to annotations (what can I say, I love meta-anything!) but just waving a flag of caution before we head heads first into the annotated unknown...

No comments: