Recipe18.6.Implementing the Proxy Pattern


Recipe 18.6. Implementing the Proxy Pattern

Problem

You want to apply the proxy pattern using AspectJ.

Solution

The proxy pattern allows the developer to provide a surrogate object in place of the actual object in case access to the real object needs to be delegated or controlled.

Example 18-9 uses the Director aspect-oriented design pattern (see Chapter 23) to provide an abstract implementation of the proxy pattern.

Example 18-9. Using an abstract aspect to define the proxy pattern
public abstract aspect ProxyPattern  {    protected interface Subject    {    }    protected abstract pointcut requestTriggered( );    private pointcut accessByCaller(Object caller) : requestTriggered( )           && this(caller);    private pointcut accessByUnknown( ) : requestTriggered( )           && !accessByCaller(Object);    Object around(Object caller, Subject subject) : accessByCaller(caller)       && target(subject)    {       if (reject(caller, subject, thisJoinPoint))       {          return rejectRequest(caller, subject, thisJoinPoint);       }       else if (delegate(caller, subject, thisJoinPoint))       {          return delegateRequest(caller, subject, thisJoinPoint);       }       return proceed(caller, subject);    }             Object around(Subject subject) : accessByUnknown( )       && target(subject)    {       // Without a caller then reject does not really make sense           // as there is no way of deciding to reject or not           if (delegate(null, subject, thisJoinPoint))       {          return delegateRequest(null, subject, thisJoinPoint);       }       return proceed(subject);    }    protected abstract boolean reject(       Object caller,       Subject subject,       JoinPoint joinPoint);    protected abstract boolean delegate(       Object caller,       Subject subject,       JoinPoint joinPoint);    protected abstract Object rejectRequest(       Object caller,       Subject subject,       JoinPoint joinPoint);         protected abstract Object delegateRequest(       Object caller,       Subject subject,       JoinPoint joinPoint); }

Discussion

Figure 18-14 shows the structure of the ProxyPattern abstract aspect and the interfaces and behavior that it defines to support the proxy design pattern.

Figure 18-14. The ProxyPattern aspect and the interfaces and behavior it defines for the design pattern's roles


The abstract aspect definition of the proxy pattern in Example 18-9 encapsulates the role of the Subject applied to objects that need proxy logic defined. For each of the two possible situations that a proxy is applied, delegation and protection, there is a defined route by which calls to the subject are examined and delegated or denied depending on the logic contained in the inheriting subaspects.

The most important advantage of this aspect implementation of the proxy pattern is that the original classes of the target application do not have to know they are going to be involved in a proxy situation. This is absolutely key since collections of objects in an application can be subjected to security and other proxy sensitive concerns without affecting the design goals of the original classes.

Example 18-10 shows how the abstract ProxyPattern aspect could be applied for a specific application. The DelegationProxy aspect defines a proxy that intercepts and delegates calls to the subject objects.

Example 18-10. Applying delegation using the ProxyPattern aspect
public aspect DelegationProxy extends ProxyPattern  {    declare parents : RealSubject implements Subject;    protected pointcut requestTriggered( ) : call(* RealSubject.write(..));    protected boolean reject(       Object caller,       Subject subject,       JoinPoint joinPoint)    {       return false;    }    protected boolean delegate(       Object caller,       Subject subject,       JoinPoint joinPoint)    {       return true;    }    protected Object rejectRequest(       Object caller,       Subject subject,       JoinPoint joinPoint)    {       return null;    }    protected Object delegateRequest(       Object caller,       Subject subject,       JoinPoint joinPoint)    {       Object[] args = joinPoint.getArgs( );       if (args != null)       {          AnotherRealSubject.write((String) args[0]);       }       else       {          AnotherRealSubject.write("");       }       return null;    } }

Figure 18-15 shows the effects when the DelegationProxy aspect is applied to the RealSubject class.

Figure 18-15. The effects of applying the proxy pattern to the RealSubject class


Figure 18-16 shows an example interaction with the aspect-oriented proxy pattern features.

Figure 18-16. Delegating the call to the write(String) method on the RealSubject class


See Also

For more information on defining abstract aspects and specializing them, see the recipes in Chapter 16; the call(Signature) pointcut is covered in Recipe Recipe 4.1; exposing join point context is examined in Recipe 13.2; the args(Type or Identifier) pointcut is described in Recipe 11.3; Recipe 11.1 describes the this(Type or Identifier) pointcut in more detail; the target(Type or Identifier) pointcut is examined in Recipe 11.2; Recipe 13.4 provides more detail on the proceed( ) call and its usage within around( ) advice; the Director aspect-oriented design pattern is explained in Recipe 23.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