Tuesday, 23 October 2012

JavaEE Revisits Design Patterns: Decorator

This time last year I wrote a series of blog posts on JavaEE implementation of design patterns. Roughly after a year, I realized I missed my favorite pattern, the decorator.

Decorator pattern is basically a way to extend functionality of an object by decorating with other objects which can wrap the target object and add their own behavior to it. If you never used or heard of decorators, I highly recommend reading chapter 3 of Head First Design Patterns.

Pretty much like other patterns mentioned in my posts before, JavaEE has an easy an elegant way to use the decorator pattern. Lets start with a simple stateless session bean.


package com.devchronicles.decorator;

import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;

/**
 *
 * @author murat
 */
@Stateless
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class EventService {
    
    public void startService(){
        System.out.println("do something important here...");
    }
}

To start implementing the decorator pattern, we need an interface so we can bind the decorators and the object to be decorated together.


package com.devchronicles.decorator;

/**
 *
 * @author murat
 */
public interface ServiceInterface {
    public void startService();
}

The interface has the method which the decorators will add functionality on. Next we need some changes on our existing EventService bean to make it decoratable.


package com.devchronicles.decorator;

import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;

/**
 *
 * @author murat
 */
@Stateless
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class EventService implements ServiceInterface{
    
    public void startService(){
        System.out.println("do something important here...");
    }
}


Now we are ready to add as much as decorator we need. All we need to do is to annotate our class, implement the ServiceInterface and to inject our service delegate.


package com.devchronicles.decorator;

import javax.decorator.Decorator;
import javax.decorator.Delegate;
import javax.inject.Inject;

/**
 *
 * @author murat
 */
@Decorator //declares this class as a decorator
public class DecoratorService implements ServiceInterface{ //must implement the service interface
    
    @Inject //inject the service
    @Delegate //and annotate as the delegate
    ServiceInterface service;

    @Override
    public void startService() { //implement the startService method to add functionality
        System.out.println("decorating the existing service!");
        service.startService(); //let the execution chain continue
    } 
}

Several decorators can be using the service interface.


package com.devchronicles.decorator;

import javax.decorator.Decorator;
import javax.decorator.Delegate;
import javax.inject.Inject;

/**
 *
 * @author murat
 */
@Decorator
public class Decorator2Service implements ServiceInterface{
     @Inject
    @Delegate
    ServiceInterface service;

    @Override
    public void startService() {
        System.out.println("decorating the service even further!!!");
        service.startService();
    }
}

Most of the configuration can be done via annotation in JavaEE6. However we still need to add some xml configuration to make decorators work. It might seem disappointing since we already annotated our decorators but still the configuration is pretty simple and needed in order to declare the order of execution. Add the following lines to the empty beans.xml.


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
           <decorators>
               <class>com.devchronicles.decorator.DecoratorService</class>
           <class>com.devchronicles.decorator.Decorator2Service</class>
           </decorators>
</beans>

When the startService method of our EventService is executed, the decorators will decorate the ejb and add their own behavior to the execution.

...

INFO: WEB0671: Loading application [Decorator] at [/Decorator]
INFO: Decorator was successfully deployed in 2,534 milliseconds.
INFO: decorating the existing service!
INFO: decorating the service even further!!!
INFO: do something important here...
...





Monday, 22 October 2012

JavaOne 2012: The Good, The Bad and The Ugly...

Just like last year JavaOne was prior to fleet week and the weather was great. It is always great to visit San Francisco and see some 'regular' JavaOne friends like Van Riper and Yakov Fain.

This was Oracle's third JavaOne and there is no more JavaOne 2.0 posts anymore. So seems like everybody already get used to the new JavaOne.

JavaOne 2012, The Good...
Although my first intentions were pretty negative against Oracle's Sun buyout and the first JavaOne which Oracle organized, it is obvious that Oracle is doing great with Java. They might still lack at understand the community but they are doing ok. Oracle is really committed to development of Java. JavaEE6 is doing great and if JavaEE7 can show a similar fast adoption, it would definitely rock. JavaEE has never been so fast, lightweight, robust and productive so Oracle really succeeded in enterprise.
JavaSE is also doing great. JavaSE8 will be introducing a variety of new concepts to Java programmers, including default methods and lambda. Oracle is really committed to the time plan so they did not hesitate to drop out features which seem to be late. This schedule commitment is good for all vendors and the community so again well done Oracle.
Java on desktop has been dead for long. Honestly I wasn't really expecting a keen support from Oracle but they are also doing good with JavaFX. I really appreciate Oracle for hiring JavaFX professionals such as Stephen Chin and giving them appropriate responsibilities. JavaFX might not be a real -strike back- but it is a good effort and the community is happy to see Oracle's commitment.
Finally it was great to see James Gosling back on the stage for the keynote.

The Bad...
JavaME is dead and finally Oracle seems to accept the fact. The mobile content was very poor. Since the Google-Oracle war on Android is over, it might be wise for Oracle to act as a step-father for Android else next year JavaOne will have no mobile content. Project Jigsaw has been left out from JavaSE8 to catch up the release date but being left to JavaSE9 clearly mean it would be too late. Again it might be wise to adopt OSGi and bundle it with JavaSE8.

and The Ugly...
The conference is getting worse in terms of content. I didn't really see as great sessions as previous years. Lack of former Rock Stars is pretty obvious. Since the Google-Oracle war is over, it would be wise to get some Google content like android and gwt. At worst since Joshua Bloch left Google, he might be back on stage next year.
The venue is getting worse. Kicking out JavaOne from Moscone and spreading the conference into three hotels was a bad idea but it is getting worse with another venue getting involved for sunday keynote. Why not using Moscone for the sunday keynote? Oracle has Moscone South, North and West where Apple and Google only rent Moscone West to perform their annual conferences. Why not sharing venues for at least the sunday keynote than sending hundreds of developers to somewhere else?  I don't really understand why Oracle insists on same dates for Oracle Open World and JavaOne.
If Oracle can not bring the old JavaOne spirit and content back, they may not find many developers to pay +$1500 to attend a conference in the following years. Honestly I wouldn't if I didn't have a session.