Recipe22.1.Applying Development Guidelines and Rules


Recipe 22.1. Applying Development Guidelines and Rules

Problem

You want to control what programmatic constructs are allowed in your application by providing a policy that is enforced at compile time.

Solution

Use the Border Controller aspect-oriented design pattern to declare a set of regions within your code. Reuse those regions when declaring any top-level rules for your project in an aspect according to the Policy pattern. Optionally extend your projects' top-level policies to specialize them for particular regions of your application.

Discussion

This solution gives you a sneak preview of two of the aspect-oriented design patterns coming in Chapter 23. Providing the foundation for this recipe's solution, the Border Controller design pattern allows you to capture your application's architecture as a set of reusable pointcuts that declare important regions within your code. Those regions can be referenced throughout the rest of the aspects in your application.

The BorderControllerAspect shown in Example 22-1 declares four regions within an example application: the withinTestingRegion() region incorporates the packages where testing code is located, withinMyApp() specifies the packages and subpackages that make up your application, withinThirdParty() specifies any areas where you may be using third-party source code, and withinMyAppMainMethod() conveniently declares the location of the main(..) method for your application.

Example 22-1. Providing a foundation for your project and application's policies by declaring the important regions within your code
package com.oreilly.aspectjcookbook; public aspect BorderControllerAspect  {    /**     * Specifies the testing region.      */    public pointcut withinTestingRegion( ) :        within(com.oreilly.aspectjcookbook.testing.+);        /**     * Specifies My Applications region.      */    public pointcut withinMyApp( ) : within(com.oreilly.aspectjcookbook.                                     myapp.+);        /**     * Specifies a third party source code region.     */    public pointcut withinThirdParty( ) :        within(com.oreilly.aspectjcookbook.thirdpartylibrary.+);        /**     * Specifies the applications main method.     */    public pointcut withinMyAppMainMethod( ) :        withincode(public void com.oreilly.aspectjcookbook.myapp.MyClass.                  main(..)); }

Example 22-1 shows only some of the areas that could be defined in an application. Other good candidates are areas where special logging is to take place, areas that are subjected to lazy loading logic, and anywhere you find it useful to formally bound parts of your architecture so that further pointcut definitions can reuse and work safely within those borders. The idea is that if those borders were to change, you would only change the Border Controller so the rest of your application's pointcut logic would immediately pick up on any relevant changes to their scope.

The Border Controller provides a useful library of reusable pointcut definitions incorporated into the Policy aspect-oriented design pattern. This pattern is used to solve this recipe's problem by declaring the different policies for your project's areas, as shown in Example 22-2.

Example 22-2. Defining a project-wide policy
package com.oreilly.aspectjcookbook; public abstract aspect ProjectPolicyAspect  {    protected abstract pointcut allowedSystemOuts( );        declare warning :         call(* *.println(..)) &&         !allowedSystemOuts( ) &&         !BorderControllerAspect.withinTestingRegion( )     : "System.out usage detected. Suggest using logging?"; }

The ProjectPolicyAspect in Example 22-2 defines the project-wide rule that messages being output to the System.out stream are to be warned against at compile time. The aspect leaves an abstract pointcut so specialized aspects can define areas where using System.out is acceptable. The specialized MyAppPolicyAspect in Example 22-3 extends the abstract ProjectPolicyAspect to declare that the testing and the thirdpartylibrary source directories are allowed to use System.out.

Example 22-3. Specializing the project-wide policy for the specifics of your application's area
package com.oreilly.aspectjcookbook.myapp; import com.oreilly.aspectjcookbook.ProjectPolicyAspect; import com.oreilly.aspectjcookbook.BorderControllerAspect; public aspect MyAppPolicyAspect extends ProjectPolicyAspect {    /**     * Specifies regions within the application where messages     * to System.out are allowed.     */    protected pointcut allowedSystemOuts( ) :        BorderControllerAspect.withinMyAppMainMethod( ) ||        BorderControllerAspect.withinThirdParty( ) ||        BorderControllerAspect.withinTestingRegion( ); }

Using the Policy and Border Controller aspect-oriented patterns, you can formalize the structure of your architecture and apply consistent project, application, package, class, and method scope policies.

See Also

The call(Signature) pointcut is described in Recipe 4.1; the within(TypePattern) pointcut is described in Recipe 9.1; the withincode(Signature) pointcut is described in Recipe 9.3; the AND (&&) operator and the OR (||) operator are described in Recipes 12.2 and 12.3 respectively; the unary NOT (!) operator is shown in Recipe 12.4; defining reusable libraries of pointcut definitions is covered in Recipe 12.6; extending the compiler with new warnings and errors is shown in Recipe 16.6; the Border Controller aspect-oriented design pattern is explained in Recipe 23.3; the Policy aspect-oriented design pattern is described in Recipe 23.4.



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