Recipe19.10.Implementing the State Pattern


Recipe 19.10. Implementing the State Pattern

Problem

You want to apply the state pattern using AspectJ.

Solution

The state pattern provides a mechanism by which an object can vary its behavior based upon its state. The state is encapsulated in its own object that is then contained by the invoked object. The invoked object passes all method requests affected by its state to the state object, which varies its response based on its class at that point in time.

Example 19-18 shows how the state of a pseudo TCPConnection class could be declared using aspects including how those states are transitioned between as methods are invoked.

Example 19-18. Implementing the State pattern for a specific application's classes using aspects
public aspect TCPConnectionState  {    protected TCPState listening = new TCPListen( );    protected TCPState acknowledged = new TCPAcknowledged( );    protected TCPState closed = new TCPClosed( );    after(TCPConnection connection) : initialization(new ( ))       && target(connection)    {       listening.setConnection(new SocketConnection( ));       connection.setState(listening);    }    after(TCPConnection connection, TCPState state) : call(       void TCPState +.acknowledge( ))       && target(state)       && this(connection)    {       if (connection.getState( ) == listening)       {          acknowledged.setConnection(listening.getConnection( ));          connection.setState(acknowledged);       }    }    after(TCPConnection connection, TCPState state) : call(       void TCPState +.close( ))       && target(state)       && this(connection)    {       if ((connection.getState( ) == listening)          || (connection.getState( ) == acknowledged))       {          connection.setState(closed);       }    } }

Discussion

The TCPConnectionState aspect specifies that the TCPConnection classes state will be listening when it is created, acknowledged when the acknowledge() method is invoked, and closed when the close( ) call is invoked. It also specifies what to do if these methods are invoked depending on their order. This is all achieved without affecting the TCPConnection class.

Aspects are used in this solution to modularize the rules for changing from one state to another. By modularizing these rules, analyzing the rules for the change of state becomes easier as they are in one place and become more flexible to future changes such as the incorporation of new or changed states without affecting the original class. This provides distinct advantages over a more traditional object-oriented approach where the logic for deciding the state changes must be embedded in the methods and, therefore, may confuse the business logic.

Figure 19-30 shows how the state of the TCPConnection is affected by the sequence of methods called on the class as managed by the TCPConnectionState aspect.

Figure 19-30. Managing the state of a TCPConnection object using the TCPConnectionState aspect


See Also

The call(Signature) pointcut is covered in Recipe Recipe 4.1; the after( ) form of advice is discussed in Recipe Recipe 13.5; the this(Type or Identifier) pointcut is described in Recipe 11.3; the target(Type or Identifier) pointcut is examined in Recipe 11.2; exposing join point context is examined in Recipe 13.2; the initialization(Signature) pointcut is examined in Recipe 7.3.



AspectJ Cookbook
Aspectj Cookbook
ISBN: 0596006543
EAN: 2147483647
Year: 2006
Pages: 203
Authors: Russ Miles

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net