Annotations, Enum, AspectJ and the State pattern

The combination of annotations and AspectJ is a hot topic worth exploring when using JSE 5.0. Recently we were discussing if this combination can be used to implement part of the State pattern. Even though I couldn’t think of any practical value for this, I implemented this code. The following code has meta-data associated with methods and this meta-data has the next state hardcoded in it. I have used Enum,annotations and AspectJ but I haven’t checked this for bugs. The State pattern example is the one by Robert C. Martin. See Aspect-Oriented Design Pattern Implementations for implementations of the GOF patterns using AOP.

package com.state;

public class Turnstile {

public void lock(){
System.out.println( "Locking" );
}

public void unlock(){
System.out.println( "UnLocking" );
}

public void alarm(){
System.out.println( "Security Breach" );
}

}
package com.state;

public class TurnstileMachine extends Turnstile {

private TurnstileState state;

public void coin() {
state.coin( this );

}

public void pass() {
state.pass( this );

}

public void setState(TurnstileState state) {
this.state = state;
System.out.println( "Changing state to " + state );
}

}
package com.state;

public abstract class TurnstileState {

public abstract void coin( TurnstileMachine t );

public abstract void pass( TurnstileMachine t );

}
package com.state;

public class UnlockedState extends TurnstileState {

@Override
public void coin(TurnstileMachine t) {

}

@Override
@StateChanger(EnumState.UNLOCK)
public void pass(TurnstileMachine t) {
//t.setState( this );
t.unlock();
}

}
package com.state;

public enum EnumState {

LOCK {
{ state = new LockedState(); }
},
UNLOCK {
{ state = new UnlockedState(); }
};

TurnstileState state;

}
package com.state;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention( RetentionPolicy.RUNTIME )
@Target({ ElementType.METHOD })
public @interface StateChanger {
public EnumState value() default EnumState.LOCK;

}
package com.state;

public aspect StateAspect {
pointcut stateChanger( TurnstileState t,
StateChanger sc,
TurnstileMachine m)
: execution( @StateChanger * *(..) )&& @annotation(sc) && this(t) && args(m);

void around( TurnstileState t,
StateChanger sc,
TurnstileMachine m ) : stateChanger( t,sc, m ){
proceed( t, sc, m );
m.setState( sc.value().state);
}
}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: