Showing posts with label aop. Show all posts
Showing posts with label aop. Show all posts

Monday, July 30, 2007

Configurable Decorators using AOP

Sometime back I had posted on the increasing misuse (or overuse) of aspects by today's developers. In many of those cases, plain old decorators would have just been fine. However, very recently, I used a combination of decorators and aspects to add another degree of configurability to a domain model.

Decorators, by design, should be lightweight objects which can be attached to the skin of other domain objects to add to the roles and responsibilities of the latter. They are added and/or removed dynamically from original objects - hence we say that decorators offer an added level of flexibility over static inheritance. Consider the following aggregate, which is modeled as a Composite :

Here is the base abstraction for the Composite, which models the Salary components of an employee :


public abstract class Salary {
  public Salary add(final Salary component) {
    throw new UnsupportedOperationException("not supported at this level");
  }

  public Salary remove(final Salary component) {
    throw new UnsupportedOperationException("not supported at this level");
  }

  public Salary getChild(final int i) {
    throw new UnsupportedOperationException("not supported at this level");
  }

  public abstract double calculate();
}



and here is the composite ..


public class SalaryComposite extends Salary {
  private List<Salary> components = new ArrayList<Salary>();

  @Override
  public Salary add(Salary component) {
    components.add(component);
    return this;
  }

  @Override
  public double calculate() {
    double total = 0;
    for(Salary salary : components) {
      total += salary.calculate();
    }
    return total;
  }

  @Override
  public Salary getChild(int i) {
    return components.get(i);
  }

  @Override
  public Salary remove(Salary component) {
    components.remove(component);
    return this;
  }
}



and a couple of leaf level components ..


public class BasicPay extends Salary {
  private double basicPay;

  public BasicPay(double basicPay) {
    this.basicPay = basicPay;
  }

  @Override
  public double calculate() {
    return basicPay;
  }
}

public class HouseRentAllowance extends Salary {
  private double amount;

  public HouseRentAllowance(double amount) {
    this.amount = amount;
  }

  @Override
  public double calculate() {
    return amount;
  }
}



Decorators and Composites - a Marriage

Decorators work nicely with Composites, and I have some decorators to allow users add behaviors to the Composite elements dynamically. In order to have decorators for the Composite, I need to have the Decorator share the base class with the Composite.


public abstract class SalaryDecorator extends Salary {
  private Salary component;

  public SalaryDecorator(final Salary component) {
    this.component = component;
  }

  @Override
  public double calculate() {
    return component.calculate();
  }
}



and a couple of concrete decorators ..

a senior citizen adjustment which can be applied to some of the components of the salary ..


public class SeniorCitizenAdjustment extends SalaryDecorator {
  protected double adjustmentFactor;
  public SeniorCitizenAdjustment(final Salary component, double adjustmentFactor) {
    super(component);
    this.adjustmentFactor = adjustmentFactor;
  }

  @Override
  public double calculate() {
    //.. calculation of absolute amount based on adjustmentFactor
    //.. complex logic
    adjustment = ...
    return super.calculate() + adjustment;
  }
}



and a city compensatory allowance which varies based on the city where the employee leaves ..


public class CityCompensatoryAdjustment extends SalaryDecorator {
  private double adjustmentFactor;

  public CityCompensatoryAdjustment(final Salary component, double adjustmentFactor) {
    super(component);
    this.adjustmentFactor = adjustmentFactor;
  }

  @Override
  public double calculate() {
    //.. calculation of absolute amount based on adjustmentFactor
    //.. complex logic
    adjustment = ...
    return super.calculate() + adjustment;
  }
}



Now my clients can make use of the Composite and decorate them using the decorators designed to compose the individual salary components ..


//..
Salary s = new SalaryComposite();
s.add(new SeniorCitizenAdjustment(new BasicPay(1000), 100))
 .add(new CityCompensatoryAdjustment(new HouseRentAllowance(300), 150));
//..



In the above example, the use of decorators provide the flexibility that the particular design pattern promises and allows instance level customization of individual components of the composite.

Decorating the Decorators

How do you handle fine grained variations within decorators ? In our case many of the decorators had fine grained variations within themselves, which calls for either inheritance hierarchies between them or some other way to decorate the decorators (super-decorators ?). The problem with static inheritance hierarchies is well-known. They have to be defined during compile time and the codebase for each deployment need to have the explosion of all possible variations modeled as subclasses. Looks like the problem that decorators are supposed to solve and that which we have already solved for the Composite Salary aggregate. Now we have the same problem for the decorators themselves.

We rejected the idea of static inheritance hierarchies and decided to model the variations as yet another level of decorators. We did not want to make the original decorators too complex and focused on making small composable, additive abstractions that can be tagged on transparently onto the domain objects and decorators alike.

e.g. in an implementation we found that the CityCompensatoryAdjustment has another fine grained variation. When CityCompensatoryAdjustment is applied, we have the additional variation that states that if the employee's residence is in one of a group of premium cities, then he is eligible for an additional premium allowance on top of the normal CityCompensatoryAdjustment. We rejected the idea of changing CityCompensatoryAdjustment to incorporate the new variations for 2 reasons :

  1. Trying to incorporate too much logic into decorators will make them complicated, which defeats the basic design motivation for the decorators

  2. These variations change across deployments - hence it will be a bloat trying to incorporate everything into a single class


Modeling the new requirement as another decorator (PremiumCityAdjustment), we have the following usage of the above snippet ..


//..
Salary s = new SalaryComposite();
s.add(new SeniorCitizenAdjustment(new BasicPay(1000), 100))
 .add(new PremiumCityAdjustment(
          new CityCompensatoryAdjustment(
              new HouseRentAllowance(300), 150),
          adjustmentFactor));
//..



But the Variations are Deployment specific!

We cannot change the main codebase with the above fine-grained variations, since they are deployment specific. We need to find out ways to externalize the invocation of these decorators. We found out that these finer variations are policies that need to change the behavior of the original decorators whenever they are applied. In the above example, every invocation of CityCompensatoryAdjustment needs to be decorated with PremiumCityAdjustment.


public class PremiumCityAdjustment extends SalaryDecorator {
  public PremiumCityAdjustment(final Salary component) {
    super(component);
  }

  @Override
  public double calculate() {
    //.. calculation of adjustment amount
    adjustment = ..
    return super.calculate() + adjustment;
  }
}



Aspects again !

We decided to implement the finer grained variations as decorators which would be applied through aspects to the original decorators. This is the base aspect for all such SuperDecorators ..


public abstract aspect SalarySuperDecoratorBase<extends SalaryDecorator> {

  pointcut decoratorCalculate(T s) : target(s)
        && execution(double T.calculate());

  abstract pointcut myAdvice();
}



and here is the implementation for adding PremiumCityAdjustment as a decorator for CityCompensatoryAdjustment ..


public aspect SuperDecoratorCityCompensatoryAdjustment
    extends SalarySuperDecoratorBase<CityCompensatoryAdjustment> {

  pointcut myAdvice(): adviceexecution()
    && within(SuperDecoratorCityCompensatoryAdjustment);

  Object around(CityCompensatoryAdjustment s) : decoratorCalculate(s) && !cflow(myAdvice()) {
    return new PremiumCityAdjustment(s).calculate();
  }
}



This way we had a set of core decorators for the main domain model and another set of deployment specific decorators which decorated the core ones through aspect weaving. By adopting this strategy we were able to keep the decorators lightweight, avoided deep inheritance hierarchies and managed to keep customizable code base completely separate from the core one.

Monday, July 02, 2007

How do you decide when to use Aspects ?

Any new technology comes with its own powerbag and it depends upon us programmers to make meaningful and responsible use of the power. New age programming languages are riding their power continuum - it is upto us to stay a blub programmer, be an average coder or try to be the hacker. But, whatever, you decide to do, make your decision an informed one - be responsible to use the power in the proper place and perspective.

Aspect oriented programming is a new buzzword that has been popularized more recently through its integration with the Spring framework. The Spring guys have done a great job in bringing a difficult technology to the masses through its usual style of declarative programming. Spring AOP takes a lot of pain out of you by offering a greatly simplified programming model to have method interceptions baked in your codebase.

But making a technology look simpler has its obvious consequences of being misused. There appears to be lots of cases with programmers where they are using aspects, when good old simple Java design patterns, make a more appropriate cut. In the last couple of months, I found Spring AOP's method interception being used in many instances (including this one in an InfoQ article) when good old decorators could have solved the problem. The basic problem which the developer was trying to solve was to wrap some command with pre- and post- advices. The AOP based solution would make sense only if the same strategy needs to be repeated in multiple places and invocations of the command, which would otherwise have resulted in lots of boilerplates littering the codebase. Otherwise, a command and a bunch of decorators can provide a scalable solution to this ..


// the generic command interface
public interface ICommand {
void execute(final Object object);
}

// and a decorator interface for decorating the command
public abstract class Decorator implements ICommand {

// the command to decorate
private ICommand decorated;

public Decorator(final ICommand decorated) {
this.decorated = decorated;
}

public final void execute(Object object) {
pre();
decorated.execute(object);
post();
}

protected final ICommand getDecorated() {
return decorated;
}

// the pre-hook
protected abstract void pre();

// the post-hook
protected abstract void post();
}

// my custom command class
public class FileCommand implements ICommand {
//.. custom command
}

// my first custom decorator
public class MyDecorator_1 extends Decorator {

public MyDecorator_1(final ICommand command) {
super(command);
}

@Override
protected void post() {
//.. custom post hook
}

@Override
protected void pre() {
//.. custom pre hook
}
}

// another custom decorator
public class MyDecorator_2 extends Decorator {

public MyDecorator_2(final ICommand command) {
super(command);
}

@Override
protected void post() {
//.. custom post hook
}

@Override
protected void pre() {
//.. custom pre hook
}
}
// stack up the decorators
new MyDecorator_2(
new MyDecorator_1(
new FileCommand(...))).execute(..);



Use Aspects to address crosscutting concerns only

I use aspects as a last resort, when all options fail to address the separation of concerns that I am looking for in my code organization. Aspects help avoid the code tangle by identifying joinpoints through pointcuts and helping define advices that will be applied to the joinpoints. But I use them only when all traditional Java tools and techniques fail to localize my solution. Aspects bring in a separate machinery, the heavy lifting of bytecode instrumentation. Spring AOP is, however, pure Java, but based on dynamic proxies, which have their own limitations in method interceptions and performance penalties (however small) of creating proxies on every call. Spring AOP has less magic than pure AOP - but use the technology only if it is the right choice for the problem at hand. At least, recently, I find many instances of this wonderful technology being misused as a result of sheer over-engineering. Often, when we see nails, everything starts to look like a hammer. Keep your solution simple, ensure that it solves the immediate problem at hand and gives you adequate options for extensibility.

Monday, February 12, 2007

Domain Driven Design - Inject Repositories, not DAOs in Domain Entities

There are some discussions in Spring forum, of late, regarding injection of repositories in the domain objects. And in the context of the data access layer, there appears to be some confusion regarding the difference between DAOs and repositories. A data access object(DAO) is the contract between the relational database and the OO application. A DAO belongs to the data layer of the application, which encapsulates the internals of CRUD operations from the Java application being developed by the user using OO paradigms. In the absence of an ORM framework, the DAO handles the impedance mismatch that a relational database has with OO techniques.

A Look at the Domain Model

In the domain model, say, I have an entity named Organization, which needs to access the database to determine statistics regarding its employees ..


class Organization {

  private String name;
  private Address corporateOffice;
  // .. other members

  public long getEmployeeCount() {
    // .. implementation
  }

  public List<Employee> getOutstationEmployees() {
    // .. access Employee table and Address table in database
    // .. and find out employees who are in a diff city than corporate office
  }
}



and I need access to the employee details deep down in my database to get the above details mandated by the Organization entity. A typical EmployeeDao will look like the following :


public interface EmployeeDao {
  List<Employee> getAllEmployees();
  Employee getEmployeeById(long id);
  List<Employee> getEmployeesByAddress(Address address);
  List<Employee> getEmployeesByName(String name);
  // .. other methods
}



Using this DAO definition and an appropriate implementation, we can have the method getOutstationEmployees() as follows :


@Configurable("organization")
class Organization {

  // implementation needs to be injected
  private EmployeeDAO employeeDao;

  // ..
  // ..

  public List<Employee> getOutstationEmployees() {
    List<Employee> emps = employeeDao.getEmployeesByAddress(corporateOffice);
    List<Employee> allEmps = employeeDao.getAllEmployees();
    return CollectionUtils.minus(allEmps, emps);
  }
  // ..
}



Note the usage of the Spring annotation @Configurable to ensure dependency injection of the employeeDao into the domain object during instantiation. But how clean is this model ?

Distilling the Domain Model

The main problem with the above model is that we have lots of unrelated concerns polluting the domain. In his book on Domain Driven Design, Eric Evans says in the context of managing the sanctity of the domain model :
An object should be distilled until nothing remains that does not relate to its meaning or support its role in interactions

In the above design, the code snippet that prepares the list of outstation employees contains lots of logic which deals with list manipulations and data fetching from the database, which do not appear to belong naturally to the domain abstraction for modeling an Organization. This detailed logic should be part of some other abstraction which is closer to the data layer.

This is the ideal candidate for being part of the EmployeeRepository, which is a separate abstraction that interacts with the data accessors (here, the DAOs) and provides "business interfaces" to the domain model. Here we will have one repository for the entire Employee aggregate. An Employee class may collaborate with other classes like Address, Office etc., forming the entire Aggregate, as suggested by Eric in DDD. And it is the responsibility of this single Repository to work with all necessary DAOs and provide all data access services to the domain model in the language which the domain understands. So the domain model remains decoupled from the details of preparing collections from the data layer.


public interface EmployeeRepository {
  List<Employee> getOutstationEmployees(Address address);
  // .. other business contracts
}

public class EmployeeRepositoryImpl implements EmployeeRepository {

  private EmployeeDAO employeeDao;

  public List<Employee> getOutstationEmployees(Address address) {
    List<Employee> emps = employeeDao.getEmployeesByAddress(corporateOffice);
    List<Employee> allEmps = employeeDao.getAllEmployees();
    return CollectionUtils.minus(allEmps, emps);
  }
}



The main differences between the Repository and the DAO are that :

  • The DAO is at a lower level of abstraction than the Repository and can contain plumbing codes to pull out data from the database. We have one DAO per database table, but one repository per domain type or aggregate.

  • The contracts provided by the Repository are purely "domain centric" and speak the same domain language.



Repositories are Domain Artifacts

Repositories speak the Ubiquitous Language of the domain. Hence we contracts which the repositories publish must belong to the domain model. OTOH the implementation of a Repository will conatin many plumbing codes for accessing DAOs and their table specific methods. Hence it is recommended that the pure domain model should depend *only* on the Repository interfaces. Martin Fowler recommends the Separated Interface pattern for this.

Injecting the Repository instead of the DAO results in a much cleaner domain model :


@Configurable("organization")
class Organization {
  private String name;
  private Address corporateOffice;
  // .. other members

  // implementation needs to be injected
  private EmployeeRepository employeeRepo;

  // ..
  // ..

  public List<Employee> getOutstationEmployees() {
    return employeeRepo.getOutstationEmployees(corporateOffice);
  }
  // ..
}



In the next part, I will have a look at the Repository implementations while using an ORM framework like Hibernate. We do not need DAOs there, since the object graph will have transparent persistence functionality backed up by the ORM engine. But that is the subject for another discussion, another day ..

Tuesday, December 26, 2006

Domain Driven Design : Control Domain Object Lifetimes using Spring Custom Scoped Beans

In his celebrated book on Domain Driven Design, Eric Evans mentions that one of the biggest challenges of maintaining the integrity of a domain model is managing the lifecycle of a domain object. He states
But other objects have longer lives, not all of which are spent in active memory. They have complex interdependencies with other objects. They go through changes of state to which invariants apply. Managing these objects presents challenges that can easily derail an attempt at MODEL-DRIVEN DESIGN.

Two points immediately stand out from the above, when we think of modeling a system based on principles of DDD :

  1. Domain object lifecycles need to be managed

  2. Lifecycle management needs to be decoupled from mainstream business logic


Both of the above issues can be addressed using an IoC container like Spring. And the new custom scopes of Spring 2.0 give us the real steroid towards declarative lifecycle management of domain objects.

Custom Scopes in Spring 2.0

Till 2.0, Spring provided only two levels of granularity at which you could declare your beans -

  1. Singleton, which scopes a single bean definition to a single object instance per Spring IoC container and

  2. Prototype, which scopes a single bean definition to any number of object instances. The prototype scope results in creation of a new bean instance every time a request for that specific bean is made.


Hence any other intermediate granularity of bean lifecycles had to be managed explicitly by the application itself. Spring 2.0 comes with three additional levels of bean scopes out of the box, as well as the framework to create your custom scope that suits your application needs. The ones that come out of the box are request, session and global session, which are described in detail in the Spring Reference documentation.

In this blog post, I will elaborate how the domain model can be enriched by defining beans at application defined custom scopes. I will end the post with an example of how declaring the scope as configuration, results in declarative lifecycle management of a domain object, irrespective of the layer to which the object belongs.

Scope your Domain Objects at Business Level Granularity

Prior to 2.0, non-singleton beans could only be defined with a lifecycle that creates a new instance on every access - aka the prototype scope. For beans not created by Spring, there used to be techniques like Field Level Injection and Service Location Strategy which achieves the same effect as prototype beans.

Let us consider a real life example from the financial domain, specifically, a back office system for Capital Market Trading and Settlement. We have an example of a BasketTrade, which is, essentially a collection of Trades matching some criteria and need to be processed together. No surprises here, we model a BasketTrade as :


public class BasketTrade {
  private List<Trade> trades = new ArrayList<Trade>();
  // ..
  // ..
}



The point to note is that the abstraction BasketTrade is just a virtual container for the collection of trades and has been created for the convenience of atomic processing of the underlying Trade objects. It is typically the root of an Aggregate, as Eric defines in his DDD book, which ceases to exist as soon as the processing is complete, e.g. all component trades are committed to the Repository.

In other words, we can define a custom scope (say, basket-scope), which defines the lifecycle of a BasketTrade bean. Typically, the application provides a BasketingService, which can be modeled as a Singleton, and can contain a BasketTrade as a scoped bean within it, injected by the IoC container.


public class BasketingService {
  private BasketTrade basket;

  public void addToBasket(Trade trade) {
    getBasket().add(trade);
  }

  public void setBasket(BasketTrade basket) {
    this.basket = basket;
  }

  public BasketTrade getBasket() {
    return basket;
  }
}



We have two collaborating beans with different lifecycles, which can be wired up with the custom scope definitions as part of the configuration. And Spring 2.0 offers ScopedProxyFactoryBean for this purpose, which offers convenient proxy factory bean for scoped objects. Here we have the xml, which wires the domain objects with custom life cycles :


<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
  <property name="scopes">
   <map>
    <entry key="basket"><bean class="org.dg.biz.trd.BasketScope"/></entry>
   </map>
  </property>
</bean>

<bean id="basketTradeTarget"
  class="org.dg.biz.trd.BasketTrade" scope="basket" lazy-init="true">
</bean>

<bean id="basketTradeProxy"
  class="org.springframework.aop.scope.ScopedProxyFactoryBean">
   <property name="targetBeanName">
    <value>basketTradeTarget</value>
   </property>
</bean>

<bean id="basketingService" class="org.dg.biz.trd.BasketingService">
  <property name="basket" ref="basketTradeProxy"/>
</bean>




Defining the BasketScope

The following is a very naive implementation of the custom basket scope. This is just for demonstrating the power of custom scopes in controlling the lifecycles of domain objects.


public class BasketScope implements Scope {
  private static final Map scope = new ConcurrentHashMap();

  public String getConversationId() {
    return null;
  }

  public Object get(String name, ObjectFactory objectFactory) {
    Object obj = scope.get(name);
    if (obj == null) {
      obj = objectFactory.getObject();
      scope.put(name, obj);
    }
    return obj;
  }

  public Object remove(String name) {
    return scope.remove(name);
  }

  public void registerDestructionCallback(String string, Runnable runnable) {
    // register any custom callback
  }
}




Removing Objects with Custom Scope

This is an area which is not very clear from Spring Reference documentation. No problem, the helpful Spring community was prompt enough to give enough support to clarify all my confusions (see this thread).

For the out-of-the-box implementations of request and session scopes, the lifetime of the scoped bean ends automatically with the end of the request or session - and one can implement HttpSessionBindingListener to plug in custom destruction callback. Have a look at the implementation of DestructionCallbackBindingListener in class org.springframework.web.context.request.ServletRequestAttributes :


private static class DestructionCallbackBindingListener
    implements HttpSessionBindingListener {

  private final Runnable destructionCallback;

  public DestructionCallbackBindingListener(Runnable destructionCallback) {
    this.destructionCallback = destructionCallback;
  }

  public void valueBound(HttpSessionBindingEvent event) {
  }

  public void valueUnbound(HttpSessionBindingEvent event) {
    this.destructionCallback.run();
  }
}



For a custom scope, the simplest way will be to invoke the object removal manually in the workflow. For the above example with BasketTrade, the destruction code looks like :


ScopedObject so = (ScopedObject) basketingService.getBasket();
so.removeFromScope();



Note that proxies returned by ScopedProxyFactoryBean implement the ScopedObject interface, which allows removing the corresponding object from the scope, seamlessly creating a new instance in the scope on next access.

And now on to a neat trick. We can encapsulate the invocation of the destruction callback into a Seam-style annotation marking the end of the conversation scope. In the above code for BasketingService, suppose we would like to end the scope of the basket after a commit to the database of all constituent trades - we have a method commit(), which after database commit will mark the end of the lifetime of the current basket. We mark this declaratively using the @End annotation.


public class BasketingService {
  // as above

  @End
  public BasketTrade commit() {
    // database commit logic
    return basket;
  }
}



Finally the implementation of @End using the usual Spring AOP magic ..


@Aspect
public class DestroyScope {

  @AfterReturning(
    pointcut="@annotation(org.dg.biz.trd.End)",
    returning="retVal")
  public void doDestroy(Object retVal) {
    ScopedObject so = (ScopedObject) retVal;
    so.removeFromScope();
  }
}



and the corresponding entry in configuration xml :


<aop:aspectj-autoproxy/>
<bean id="destroyAspect" class="org.dg.biz.trd.DestroyScope"></bean>



Conclusion

One of the great benefits of custom scopes in Spring 2.0 is the fact that it allows declarative lifecycle management of domain objects without the service location api intruding your business logic code. In the above example, the two wired beans BasketingService and BasketTrade have different lifecycles - yet the collaborating code and the associated business logic is completely oblivious about this difference. The declarative @End annotation, along with the Spring AOP magic, works behind the doors to automatically fetch a new instance of BasketTrade when the user asks for the next access.

Tuesday, December 12, 2006

Domain Driven Design : Service Injection Strategies in Spring and their Pitfalls - Part 2 - Service Injection into Aspects

In Part 1 of this series, I had discussed one way of injecting services into domain objects not instantiated by the Spring container - the @Configurable annotation, which provides a nice declarative semantics for encouraging rich domain models. I had also pointed out some of the pitfalls which can bite you in course of the implementation using the @Configurable technique.

One of the highlights to remember regarding the @Configurable approach is that the annotation works on a per-class basis and cannot be meaningfully enforced on class hierarchies all at once. Let us consider the case where we need to inject a service to a number of domain classes, not related by inheritance. I came across this situation recently in modeling the financial domain for developing a solution for a capital market back office system.


class Trade {
  // models a trade of a security for an account
}

class Settlement {
  // models a settlement of a trade
}

class Position {
  // models the security and cash position of an account
}



These three are only examples of some of the many domain classes which needed a validation sevice for the account on which they operate. It is fairly simple to inject the validation service using @Configurable - note that being domain classes, these are not instantiated by Spring container. Hence @Configurable works like a charm !


@Configurable("trade")
class Trade {
  private IAccountValidationService accountValidationService;
  // setter ..
  // ..
}

@Configurable("settlement")
class Settlement {
  private IAccountValidationService accountValidationService;
  // setter ..
  // ..
}

@Configurable("position")
class Position {
  private IAccountValidationService accountValidationService;
  // setter ..
  // ..
}



and we have the corresponding applicationContext.xml :


<bean id="trade"
  class="org.dg.biz.Trade" scope="prototype">
  <property name="accountValidationService">
  <ref bean="defaultAccountValidationService"/>
  </property>
</bean>

<bean id="settlement"
  class="org.dg.biz.Settlement" scope="prototype">
  <property name="accountValidationService">
  <ref bean="defaultAccountValidationService"/>
  </property>
</bean>

<bean id="position"
  class="org.dg.biz.Position" scope="prototype">
  <property name="accountValidationService">
  <ref bean="defaultAccountValidationService"/>
  </property>
</bean>

<bean name="defaultAccountValidationService"
  class="org.dg.biz.DefaultAccountValidationService">
</bean>



One of the disturbing points of the above configuration is the boilerplate repetition of the service injection for accountValidationService. If tomorrow we need to change the validation strategy, we need to change entries for all of them separately - a violation of DRY. And had it not been for this service, we need not have an entry in the configuration file for these domain classes at all !

When Dealing with Repetitions, Think Aspects

Clearly the above domain classes cannot be related through any common parentage - so we cannot capture them directly on their head. Why not have an extra level of indirection that enables us to do so ? Adrian Coyler explains this strategy succinctly in this article and I will try to summarise my experience in using it in a domain modeling exercise.

Let us have the domain classes themselves advertise the services that they want to subscribe to ..


class Trade implements IAccountValidationClient {
  // ..
}

class Settlement implements IAccountValidationClient {
  // ..
}

class Position implements IAccountValidationClient {
  // ..
}



Aha .. now at least we have the head to catch - we need to determine how we can inject the service in all of them using the head. Think Pointcuts ..


pointcut clientCreation(IAccountValidationClient aClient) :
  initialization(IAccountValidationClient+.new(..)) &&
  !initialization(IAccountValidationClient.new(..)) &&
  this(aClient);



This will capture all instantiations of classes that subscribe to account validation service by implementing IAccountValidationClient. Once we have the instantiations intercepted through a pointcut, can we inject a service into each of them through an aspect ? Note that the service injection cannot be done through inter-type declarations or type introductions, since all of the classes will actually be using the service in-situ, while inter-type declaration introduces the new service off-site in the aspect definition. e.g.


class Trade implements IAccountValidationClient {
  // ..

  public void validate(..) {
    // validate account using validation service
    // the validation service has to be declared in-situ
  }
}



Inject the Service into an Aspect

Create an aspect with the above pointcut, inject the service into it and use the injected service in an aspect advice to reinject it into the client using the matching joinpoint. The only question is how to inject the service into an aspect .. and this is where Spring rocks. Spring allows you to specify a factory method which the container will use for instantiation of the bean. And AspectJ exposes the method aspectOf for every aspect, which precisely fits the situation like a glove. Marry the two and what you have is pure magic :


<bean name="accountValidationServiceInjector"
  class="org.dg.biz.AccountValidationServiceInjector"
  factory-method="aspectOf">
  <property name="service"><ref bean="accountValidationService"/></property>
</bean>



The aspect gets the service injected after instantiation through the aspectOf factory method.

The Missing Block in the Puzzle - the Advice that Gets Weaved

Here is the complete aspect :


public aspect AccountValidationServiceInjector {
  private IAccountValidationService service;

  public void setService(IAccountValidationService service) {
    this.service = service;
  }

  pointcut clientCreation(IAccountValidationClient aClient) :
    initialization(IAccountValidationClient+.new(..)) &&
    !initialization(IAccountValidationClient.new(..)) &&
    this(aClient);

  after(IAccountValidationClient aClient) returning :
    clientCreation(aClient) {
    if (aClient.getAccountValidationService() == null) {
      aClient.setAccountValidationService(this.service);
    }
  }
}



and the relevant portions of a client :


public class Settlement implements IAccountValidationClient {

  private IAccountValidationService accountValidationService;

  public IAccountValidationService getAccountValidationService() {
    return accountValidationService;
  }

  public void setAccountValidationService(
    IAccountValidationService aValidationService) {
    this.accountValidationService = aValidationService;
  }

  // ...
}



It does not need the @Configurable annotation and hence the configuration boilerplates disappear. And if we need to change the validation strategy, we need to change only one entry for the aspect accountValidationServiceInjector in the applicationContext.xml.

Strategy Specialization using @Configurable

The above technique injects an implementation of a service across all domain objects that publish their willingness for the service. It may so happen, that some of them may need to go for a specialized service implementation.

e.g. in our domain, the account validation service for Position needs to check if the Position Management Service is subscribed for the account in the contract with the Custodian. This calls for a special validation service to be injected for Position class. This can be done using @Configurable on top of the above generalized injection.


@Configurable("position")
class Position {
  private IAccountValidationService accountValidationService;
  // setter ..
  // ..
}



Here are the corresponding entries in applicationContext.xml for the specialized service :


<bean name="specialAccountValidationService"
  class="org.dg.biz.SpecialAccountValidationService">
</bean>

<bean id="position"
  class="org.dg.biz.Position"
  scope="prototype">
  <property name="accountValidationService">
    <ref bean="specialAccountValidationService"/>
  </property>
</bean>



With the above specialization, all classes implementing IAccountValidationClient will be injected with DefaultAccountValidationService, except Position, which will get an instance of SpecialAccountValidationService. Note that this may require an explicit setting of aspect precedence as I mentioned in Part 1.

Pitfalls

I found the above technique quite useful in injecting common services to domain classes at large. The main advantages were realized with reduced size of the configuration xml and ease of adaptability to changes in implementation.

The main pitfall with this approach is with respect to injection upon deserialization (the same as @Configurable), which can be addressed using the same technique that Ramnivas has adopted in fixing @Configurable.

Another pitfall of this approach is that all clients need to implement the interface explicitly and have the setters programmed within the domain class. But this is a one time effort and has no impact on future changes to service implementation. It may be an interesting exercise to use Java Generics to reduce the boilerplates that need to be coded in the domain abstractions. The important point to consider here is that every domain class may implement multiple service clients - I tried to model this with Java Generics, but only banged my head with type erasure getting in the way ..


class Trade implements IAppClient<IAccountValidationService>, IAppClient<IAuditService> {
  // ..
}



No good in the current implementation of Java generics.

In the next part of this series, I will have a look at the non-singleton services and how the new Spring 2.0 scoped beans can provide an elegant solution for some such typical use cases. For now, I need some more caffeine kick .. Spring 2.0.1, the NetBeans platform, the new release of Scala .. too many toys to play around with in my list for now ..

Thursday, December 07, 2006

Domain Driven Design : Service Injection Strategies in Spring and their Pitfalls - Part 1

One of the exciting features that Spring 2.0 offers is the ability to inject dependencies into arbitrary domain objects, even when the domain object has not been created by Spring. This is achieved by using the annotation @Configurable on the domain object. I have blogged on this before and had described how this declarative dependency injection helps us in architecting rich domain models.

@Configurable is based on AspectJ's powerful AOP support, though the user can be blissfully oblivious to the nitty gritties of the implementation. In this post, I would like to discuss some of the pitfalls of @Configurable, as it stands today, with Spring 2.0.1. This will open up a discussion towards other strategies of service injection in domain objects using the combination of Spring DI and aspects. I plan to model this to be a nice little series discussing the various service injection strategies, their applications and their pitfalls. Hence the optimistic Part 1 in the title line. Stay tuned ..


@Configurable - Do I need to care about the implementation ?

The Spring reference documentation says
The @Configurable annotation marks a class as eligible for Spring-driven configuration.

This statement gives us a nice declarative semantics for dependency injection into objects not instantiated by Spring. Cool .. but unfortunately as they say, the devil is in the details. And, as a user of this contract, I still need to care about the fact that the semantics of this annotation has been implemented using an aspect. Aspects, provided by the framework, which weave into application code, always tend to be invasive, and there can be side-effects, if I have to plug in my own aspect into the very same domain object. Recently in one of the domain model implementations, I had to introduce explicit precedence on aspects to get my desired functionality :


public aspect Ordering {
  declare precedence: *..*AnnotationBeanConfigurerAspect*, *;
}



So, implementation of @Configurable, may have side-effects on user code. Watch out ..


@Configurable - Not Inheritance Friendly

Spring reference documentation does not mention this explicitly, but the fact is that @Configurable does not handle inheritance correctly. This is related to the implementation mechanism of initialization joinpoints. In case of a pointcut matching an instance with a superclass and a superinterface (e.g. class Implementation extends Parent implements Interface), three initialization joinpoints will be identified - one for the instance (Implementation), one for the superclass (Parent) and one for the superinterface (Interface). Hence the advice will also be executed thrice, once for every matching joinpoint.

@Configurable implementation is based on the AnnotationBeanConfigurerAspect, which is implemented in AspectJ. The following is the corresponding pointcut definition :


public aspect AnnotationBeanConfigurerAspect extends AbstractBeanConfigurerAspect {
  // ...
  protected pointcut beanCreation(Object beanInstance) :
    initialization((@Configurable *).new(..)) && this(beanInstance);
}



while the advice comes from the base aspect :


public abstract aspect AbstractBeanConfigurerAspect extends BeanConfigurerSupport {

  @SuppressAjWarnings("adviceDidNotMatch")
  after(Object beanInstance) returning : beanCreation(beanInstance) {
    configureBean(beanInstance);
  }
  // ...
}



Note that the pointcut is based on the initialization joinpoint of the bean instance. If the annotation is used on a class which has one or more parents in the inheritance hierarchy, then the method configureBean() will be executed once for every matching joinpoint. Now, configureBean() is idempotent - hence the end result will be the same. But still there is a performance overhead for multiple executions of the method.

e.g.


public class Trade {
  // ...
}

@Configurable("cashTrade")
public class CashTrade extends Trade {
  // ...
}



For the above example, issuing a new CashTrade() will invoke configureBean() twice on the instance created.


@Configurable and Deserializability

Deserializing a @Configurable object loses all its injected dependencies. In a clustered environment where serializing and deserializing is a common phenomenon, this is a real problem. Currently the only way to overcome this issue is for the user to write a subaspect of AbstractBeanConfigurerAspect, which takes care of restoring the dependencies on deserialization. While this solves the problem for the user, ideally this should have been taken care of by the framework. The good part is that, Ramnivas has already posted a patch for this problem in the Spring JIRA, which solves the problem almost completely. As he mentions in the comment, the solution will be exactly foolproof with a minor change in the next release of AspectJ.

Apart from the above 3 pitfalls, there are some other problems with @Configurable related to bean location failures for AnnotationBeanConfigurerAspect in hierarchical contexts. Compared to the above three, this is a more specialized occurrence since hierarchical contexts are comparatively rare.

Next time when you use @Configurable, keep an eye on these gotchas. While none of these problems are unsurmountable and we will have the fixes in future releases, these are the pitfalls that we need to consider today when deciding on the service injection strategy for domain objects. In the next part of this series, we will look at yet another strategy for service injection, which uses Spring IoC to inject dependencies into aspects instead of objects. There are situations where we may prefer the latter approach over the more user-friendly @Configurable, but that is the subject of another post, another day ..

Monday, October 09, 2006

AOP : Writing Expressive Pointcuts

Aha .. yet another rant on AOP and pointcuts, this time expressing some of the concerns with the most important aspect of aspects - the Pointcut Descriptors. In order for aspects to be a first class citizen of the domain modeling community, pointcut descriptors will have to be much more expressive than what they are today in AspectJ. Taking an example from one of the threads in "aspectj-users" forum, AOP expert Dean Wampler himself had made a mistake between call( @MyAnnotation *.new(..) ) and call( (@MyAnnotation *).new(..) ), while answering a query from another user. While the former pointcut matches all constructors annotated with @MyAnnotation, the latter matches constructors in classes where the class itself has the same annotation.

This is, at best, confusing - the syntax is not expressive and liberal sprinkling of position dependent wild card characters pose a real challenge to the beginners of AspectJ. Dean has some suggestions in his blog for making pointcut languages more expressive - as Dean has pointed out, the solution is to move towards a flexible DSL for writing pointcuts in AspectJ.

What we write today as :


execution(public !static * *(..))


can be expressed more effectively as :


execution(
  method()
  .access($public)
  .specifier(!$static)
)



The experts need to work out the complete DSL to make life easier for the beginners.


Pointcuts can be Intrusive

If not properly designed, pointcuts can directly bite into the implementation of abstractions. Consider the following example from the classic An Overview of AspectJ paper by Kiczales et. al. :


interface FigureElement {
  void incrXY(int x, int y);
}

class Point implements FigureElement {
  int x, y;
  // ...
}



Now consider the following two pointcuts :


get(int Point.x) || get(int Point.y)


and


get(* Shape+.*)


Both the above pointcuts match the same set of join points. But the first one directly intrudes into the implementation of the abstraction accessing the private fields, while the latter is based only on the interface. While both of them will have the same effect in the current implementation, but certainly, the first one violates the principle of "programming to the interface" and hence is not modular and scalable. While pointcuts have the raw power to cut into any levels of abstraction and inject advice transparently, care should be taken to make these pointcuts honor the ageold abstraction principles of the object oriented paradigm. As Bertrand Meyer has noted about OO contracts, pointcuts should also be pushed up the inheritance hierarchy in order to ensure maximal reusability.

Jonas Boner, while talking about invasive pointcuts has expressed this succinctly in his blog :
A pointcut can be seen as an implicit contract between the target code and the artifact that is using the pointcut (could be an aspect or an interceptor).
One problem with using patterns like this is that we are basing the implicit contract on implementation details, details are likely to change during the lifetime of the application. This is becoming an even bigger problem with the popularity of agile software development methodologies (like XP, Scrum, TDD etc.), with a high focus on refactoring and responsiveness to customer ever-changing requirements.


Metadata for Expressiveness

Ramnivas Laddad has talked about metadata as a multidimensional signature and has described annotations as a vehicle to prevent signature tangling and express any data associated with your code's crosscutting concerns. While annotations make code much more readable, but it is a compromise on one of the most professed principles of AOP - obliviousness. Annotations (and other mechanisms) can also be used to constrain advice execution on classes and interfaces. There have also been suggestions to have classes and interfaces explicitly restrict aspects or publish pointcuts. All of these, while publishing much more powerful interfaces for abstractions, will inherently limit the obliviousness property of AOP. See here for more details.

Use metadata to enhance the artifact being annotated, but the enhancement should be horizontal and NOT orthogonal. e.g. a domain model should always be annotated with domain level metadata and, as Jonas has rightly pointed out, it is equally important to use the Ubiquitous Language for annotating domain artifacts. Taking cue from the example Ramnivas has cited :


@Transactional
@Authorized
public void credit(float amount);



If the method credit() belongs to the domain model, it should never be annotated with service level annotations like @Transactional and @Authorized. These annotations go into service layer abstractions - the domain layer can contain only domain level metadata. Accordingly the pointcut processing for domain layers should not contain service layer functionality.