Monday, September 25, 2006

Domain Driven Design : The Leaky Model AntiPattern

Lots of people have blogged about the importance of maintaining the sanctity of the domain model in a domain driven architecture. Everyone agrees in principle that the domain model should encapsulate the domain logic to the fullest, that the service layer should be lean and the Web layer should not intrude into the implementations of the domain model.

Well, that's great for a starter! Approaching the entree, we find things moving south when various forums in TSS and Spring, Yahoo groups and individual blogs start discussing about domain models going anemic through rich service and presentation layers. Many people have suggested using the DTOs to force a separation between the domain layer and the presentation layer and getting rid of the dreaded LazyInitializationException from Hibernate-backed persistence layer. DTOs create an extra level of indirection to ensure the separation and form a valid architectural paradigm for use cases of distribution and serialization of deep nested object graphs. For others, where all layers are colocated and possibly replicated using clustering, we should always try to maximize the reachability of the domain model.

Domain Model is Crosscutting

The domain model is built upon the layers below it and serves all the layers above it. The domain layer itself encapsulates the business logic and provides fine grained behavioral POJOs to the service layer. The service layer builds up coarse-grained services out of the POJOs exposed by the domain layer and serves the presentation layer above. Hence the POJOs of the domain layer crosscuts all layers above it although exposing different views to each of them. For a particular domain entity, the interface that it publishes within the domain layer may be different from the interface that it exposes to the service or web layer. Hence we need to ensure that the model enforces this multiplicity of interfaces and prevents any implementation specific artifact leaking out of the domain layer.

Let us have a look at a real life example ..

A Domain POJO Exposing Implementation

A domain level POJO named Order, which contains a List of Items ..


package org.dg.domain;

import java.util.List;

public class Order {
  private int orderNo;
  private String description;
  private List<Item> lineItems;

  public Order(int orderNo, String description) {
    this.orderNo = orderNo;
    this.description = description;
  }

  /**
   * @return Returns the description.
   */
  public String getDescription() {
  return description;
  }

  /**
   * @param description The description to set.
   */
  public void setDescription(String description) {
    this.description = description;
  }

  /**
   * @return Returns the orderNo.
   */
  public int getOrderNo() {
    return orderNo;
  }

  /**
   * @param orderNo The orderNo to set.
   */
  public void setOrderNo(int orderNo) {
    this.orderNo = orderNo;
  }

  /**
   * @return Returns the lineItems.
   */
  public List<Item> getLineItems() {
    return lineItems;
  }

  /**
   * @param lineItems The lineItems to set.
   */
  public void setLineItems(List<Item> lineItems) {
    this.lineItems = lineItems;
  }

  public float evaluate( .. ) {
  }
}



This is a typical implementation of a domain POJO containing all getters and setters and business logic methods like evaluate(..). As it should be, it resides in the domain package and happily exposes all its implementation through public methods.

Leaky Model Symptom #1 : Direct Instantiation

The first sign of a leaky domain model is unrestricted access to class constructor thereby encouraging uncontrolled instantiations all over. Plug it in, make the constructor protected and have a factory class take care of all instantiations.


public class Order {
  // same as above

  protected Order(int orderNo, String description) {
    ..
  }
  ..
}

package org.dg.domain;

public class OrderFactory {
  public Order createOrder(int orderNo, String description) {
    return new Order(orderNo, description);
  }
}



If u feel the necessity, you can also sneak in a development aspect preventing direct instantiation even within the same package.


package org.dg.domain;

public aspect FlagNonFactoryCreation {
    declare error
      : call(Order+.new(..))
      && !within(OrderFactory+)
      : "OnlyOrderFactory can create Order";
}



Leaky Model Symptom #2 : Exposed Implementation

With the above implementation, we have the complete Order object exposed to all layers, even though we could control its instantiation through a factory. The services layer and the presentation layer can manipulate the domain model through exposed setters - a definite smell in the design and one of the major forces that have forced architects and designers to think in terms of the DTO paradigm.

Ideally we would like to have a restricted view of the Order abstraction within the web layer where users can access only a limited set of contracts that will be required to build coarse-grained service objects and presentation models. All implementation methods and anemic setters that directly manipulate the domain model without going through fluent interfaces need to be protected from being exposed. This plugs the leak and keeps the implementation artifacts locked within the domain model only. Here is a technique that achieves this by defining the restricted interface and weaving it dynamically using inter-type declarations of AOP ..

// Restricted interface for the web layer


package org.dg.domain;

import java.util.List;

public interface IOrder {
  int getOrderNo();
  String getDescription();
  List<Item> getLineItems();
  float evaluate( .. )
  void addLineItem(Item item); // new method
}



// aspect preventing leak of the domain within the web layer


package org.dg.domain;

public aspect FlagOrderInWebLayer {
  pointcut accessOrder(): call(public * Order.* (..))
          || call(public Order.new(..));

  pointcut withinWeb( ) : within(org.dg.web.*);

  declare error
    : withinWeb() && accessOrder()
    : "cannot access Order within web layer";
}



Note that all setters have been hidden in IOrder interface and an extra contract has been exposed to add an Item to an existing Order (addLineItem(..)). This makes the interface fluent and closer to the domain user, since he will typically be adding one item at a time to an Order.

Finally, weave in the IOrder interface dynamically through inter-type declarations of AspectJ, when exposing the Order abstraction to the layers above. In fact every layer to which the full abstraction of Order has been restricted can make use of this new interface.


package org.dg.domain;

public aspect RestrictOrder {
  declare parents: Order implements IOrder;

  public void Order.addLineItem(Item item) {
    this.getLineItems().add(item);
  }
}



Hence, the web layer does not get access to the full implementation of Order and has to work with the restricted contract of IOrder, thereby preventing the leaky domain model antipattern.

Tailpiece

Now that we have agreed to plug in the holes of the leaky domain model, how should we decide upon the composition of the published restricted interface ?

I find some dichotomy here. The published interface should, on one hand, be restrictive, in the sense that it should hide the implementation contracts from the client (the web layer, in the above case). While, on the other hand, the published interface has to be humane and should follow the principles of Intention-Revealing Interfaces. The interface should add convenience methods targetted to the client, which will help him use the object more effectively and conforming to the Ubiquitous Language.

Monday, September 18, 2006

Domain Driven Design : Managing Variability

The Spring guys have started talking about Domain Driven Design. And, logically so, they are talking sense. In SpringOne 2006, there were three sessions on domain driven design. Ramnivas Laddad, known as the AOP guy (recently joined Interface 21) talked about how DI and AOP help bring out the best in DDD - a minimalistic service layer, rich domain layer and fluent interfaces. Steven Devijver of Interface 21 and Grails fame discussed about rich domain modeling through usage of design patterns for managing complexity in the service layer. He emphasized on important aspects like separation of concerns through layering, AOP, IoC etc. Immutability is important to maintain the sanity of your model - make classes immutable as much as you can and focus on controlled exposure. Do not expose the internals of your implementation - public setters are evil. In a nutshell the domain model should expose only the domain language, which the domain experts speak. Make your interfaces and public contracts speak the UBIQUITOUS LANGUAGE. In another session on The Art of Domain Modeling, Keith Donald of Interface 21, talked about techniques for distilling the domain and abstracting the acquired knowledge into the domain model. All in all, it looks like the Spring guys are up for a DDD funfeast !

Variablity! Variability!

Making the domain model flexible and generative is all about managing the variabilities within the model. The better you manage the variable components of the model, the more configurable, customizable and flexible it becomes. In the last post I talked about the configuration knowledge, which will act as the generator and do the plumbing for you. It is this variability that makes the most of your configuration knowledge. The aspects of your design, specific implementations, lifecycles, scoped instances, algorithms, strategies etc. are the aspects that you would like NOT to be hardwired within your Java / C++ codebase.

Strategically Speaking ..

Over the years, I have found many variants of the Strategy pattern implementation being used to manage variabilities within the model. GOF discusses two variations in C++ - one using runtime polymorphism and virtual functions, while the other using templates and compile time polymorphism. Each has its own merits and can be applied to solve specific problems in a specific context.

The following snippet shows how the Strategy Design Pattern can be applied through runtime polymorphism to externalize the domain process of accrual calculation ..

class AccrualCalculation {

  private CalculationStrategy strategy;

  // setter injection
  public void setStrategy(CalculationStrategy strategy) {
    this.strategy = strategy;
  }

  // delegate to strategy
  public BigDecimal calculate(...) {
    return strategy.calculate(...);
  }
}

interface CalculationStrategy {
  BigDecimal calculate(...);
}

class DefaultCalculationStrategy implements CalculationStrategy {
  public BigDecimal calculate(...) {
    // implementation
  }
}

// externalize the variability through the configuration knowledge
<bean id="calcStrategy" class="com.x.y.DefaultCalculationStrategy"/>

<bean id="accrual" class="com.x.y.AccrualCalculation">
  <property name="strategy">
    <ref bean="calcStrategy"/>
  </property>
</bean>

Compare this with the same pattern implemented using generics, where the class AccrualCalculation can be designed as being parameterized on the strategy.

class AccrualCalculation<S extends CalculationStrategy> {
  private S strategy;

  // delegate to strategy
  public BigDecimal calculate(...) {
    return strategy.calculate(...);
  }
}

// usage
interest =
  new AccrualCalculation<DefaultCalculationStrategy>().calculate(...);

Traits techniques, the else-if-then of types (ah! I love the name) have also been used extensively by the C++ community to manage variations at the type level. The traits classes and traits templates along with killer metaprogramming capabilities have been used to develop blazing applications in C++. Another variant of compile time strategy is the Policy Based Design of Alexandrescu. Policy classes, along with their capabilities of having an unbounded number of implementations, provide an ideal alternative for plugging in compile time strategies to the domain model.

The Strategy Design Pattern provides an ideal mechanism to encapsulate the coarse-grained variabilities of your domain model. Spruce up the pluggability of your model by externalizing the strategy implementation into an IoC container or any other generator (as the configuration knowledge).

Fine Grained Variability with Template Method

The Template Method Design Pattern is meant for plugging in fine-grained variabilities of your algorithm / strategy within the commonality framework. Use this pattern in your model if the macro level flow of your domain process is invariant, while there are customizable bits and pieces that need to be hooked and externalized. I have used this pattern with great success in modeling rule based big financial applications. The following is an example for implementing fine grained variability using the Template Method Design Pattern. Here, the overall accrual calculation algorithm is final, while there are some hooks that need to be plugged in by the derived classes. These hooks are kept as abstract methods in the base class.

abstract class AccrualCalculation {
  public final BigDecimal calculate(...) {
    // hook
    int days = calculateAccruedDays(...);
    if (days != 0) {
      // invariant logic
    } else {
      // hook
      boolean stat = isDebitAccrualAllowed(...);
      if (stat) {
        // invariant logic
      }
      // invariant logic
    }
  }

  protected abstract int calculateAccruedDays(...);
  protected abstract boolean isDebitAccrualAllowed(...);
}


Negative Variability

Jim Coplien first introduced this term in the design and analysis space with his work on Multiparadigm Design in C++. When some of the members of an otherwise common hierarchy violate a few of the base class assumptions, he calls this negative variability. Cope goes on to say
Negative variability violate rules of variation by attacking the underlying commonality - they are the exceptions to the rules.

There are quite a few techniques for implementing negative variability viz. template specialization in C++, conditional compilation etc. The Bridge Design Pattern is also known to address this problem very well. Coplien's Multiparadigm Design book details a lot of them - have a look at the deep insights of this guru. In real life, a domain model often displays this behavior and you need to take proper care through usage of appropriate patterns and idioms.

Wednesday, September 13, 2006

Is Your Domain Model Generative ?

Martin Fowler defines a domain model as an object model of the domain that incorporates both behavior and data. If the domain is complex, then the domain model has to be complex and consequently the object model will also have to be rich and complex. Unfortunately some of the modern technologies (aka Entity Beans of J2EE) have encouraged a programming model where the domain model becomes anemic and the complexity of the domain sneaks into a procedural Service Layer. Martin Fowler's P of EAA and Erik Evans' DDD books talk enough of these anti-patterns and recommends all the virtues to have a behaviorally rich domain model in a layered architectural stack.

Generative Domain Models

Czarnecki and Eisenecker mention about another important attribute regarding richness of domain models - Generativity. A generative domain model is one that offers users the ability to order specific products or artifacts by specifying combinations of concrete implementations as configuration knowledge. More specifically
The key to automating the manufacture of systems is a generative domain model, which consists of a problem space, a solution space, and the configuration knowledge mapping between them.

What exactly do we mean by the model being generative ?

Apart from achieving high intentionality in modeling domain concepts, and promoting reusability and adaptibility, a generative domain model simplifies the process of manufacturing variants of a component / module through changes in externalized configuration knowledge. The model needs to have a unified architecture based on the commonalities of the domain with appropriate declarative hooks for plugging in variabilities.

Czarnecki and Eisenecker specify the following implementation techniques for generative models :

  • Generic Programming

  • Metaprogramming

  • C++ Template based programming

  • Aspect Oriented Programming


Of course, this is from a 1999 setting and we have many more popular programming paradigms practiced today which can promote generative domain model designs. In this post I will try to ruminate on some of these paradigms and practices and emphasize the importance of making models generative.

IoC using Spring

Spring, as an IoC container, offers strong bean management, with control over object lifecycle and dependency resolution. As configuration knowledge, it offers a DSL in the form of an XML, which the user can manipulate to wire specific implementations, inject new dependencies and weave new aspects. The user can program to interfaces and can *order* specific implementations through the DSL.

<bean id="myInventoryManager" class="org.dg.wire.InventoryManagerDefaultImpl"/>

<bean id="myProductManager" class="org.dg.wire.ProductManagerDefaultImpl">
  <property name="inventoryManager">
    <ref bean="myInventoryManager"/>
  </property>
  <property name="retrieveCurrentStock">
    <value>true</value>
  </property>
</bean>


In the above fragment of the configuration knowledge (the configuration XML of Spring), the user can declaratively supply implementations for myInventoryManager and myProductManager and control instantiations and lifecycle for all the Spring managed beans. I think this is generative domain modeling, where I can create concrete instances of my managed beans by providing implementation specific information to the configuration knowledge.

Te above example is a simplistic one and IoC containers generally provide many sophisticated features for complex bean management along with lifecycle semantics, scoped instantiations, constructor and setter based injections and dependency management. Add to that the complete declarative semantics through some form of DSLs (mostly XML based) - and you have the generativity non-intrusively weaved into your domain model.

Metaprogramming

One of the classic examples of a metaprogramming platform is Ruby on Rails, that offers amazing capabilities of generative modeling and programming. The abstraction of ActiveRecord in RoR provides a full-blown (well, almost) ORM framework for wrapping your database tables and providing access to all data and metadata. You just create a subclass of ActiveRecord::Base and you create an entire machinery to access all details of your database table.

class Order < ActiveRecord::Base
end


With just these 2 lines of code, RoR will create for you the entire model for Order, which maps to your database table Orders. RoR values convention-over-configuration - all conventions are stored in the configuration knowledge. You want to change 'em .. you are welcome .. just change ActiveRecord::Base.pluralize_table_names to false in environment.rb of the config directory and you can disable the pluralization of tables.

Traditional ORM frameworks use the mapping path, offering an object-oriented view of the world, while RoR employs the wrapping framework with a database-centric view of the world. But, whatever be it, RoR offers strong code generation capabilities using its metaprogramming engine. And the heart of it is, of course, the nice little DSL that it exposes to the world and allows users a rich set of configurability. It's generativity, at its best!

Aspect Oriented Programming

It is a well-established fact that the technology of AOP has been used extensively to address cross-cutting concerns of domain models. Transactions, security, logging, tracing, auditing etc. are best implemented in the domain model as aspects. Aspects are maintained separately from the codebase and are weaved dynamically (loadtime / runtime / compiletime) with the codebase. And because of this externalization, implementation of strategies can be changed declaratively within the domain model.

As an example, let us consider a model for a PaymentService, where the service needs to be controlled by a failover strategy. The actual implementation of the strategy can be externalized in the form of an aspect and weaved lazily with the model implementation. The following implementation has been adopted from Ramnivas Laddad's presentation at SpringOne.

public aspect PaymentServiceFailover {
  pointcut process(PaymentProcessorprocessor)
    : execution(*PaymentProcessor.*(..)) && this(processor);

  Object around(PaymentProcessorprocessor)
    : process(processor) {
      int retry = 0;
      while (true) {
        try {
        return proceed(processor);
        } catch(RemoteException ex){
          processor = getAlternativeProcessor(processor);
          ... give up logic ...
      }
    }
  }
  ...
}


Using Spring, we can inject the list of available processors declaratively and setup the complete configuration knowledge to use this specific failover strategy implementation.

public aspect PaymentServiceFailover {
  ...
  public setProcessors(List<PaymentProcessor> processors) {
    this.processors = processors;
  }
  private List<PaymentProcessor> processors;
  ...
}

<bean id="paymentServiceFailover"
  class="PaymentServiceFailover" factory-method="aspectOf">
    <property name="processors">
    <list>
      <ref bean="aProcessor"/>
      <ref bean="anotherProcessor"/>
    </list>
  </property>
</bean>


So, in the above example, we have successfully kept the implementation specific mappings externalized from the domain model. This results in the model being able to generate specific instances of PaymentService components with different implementations of failover strategies. Generativity !!

Conclusion

In summary, generative domain models offer more flexibility in practice. The invariant part of the domain resides within the model proper, while the variations are plugged into using DSLs as configuration knowledge. In practice there are many patterns to manage the variabilities within the scheme of the common architecture. But that's for another day. In the next post on domain models, I will talk about the benefits of a generative domain model in a layered architecture stack and how the service layer continues to shrink with a powerful domain model in place.

Tuesday, September 12, 2006

Loads of Fun with StrongTalk

Gilad Bracha has announced the open sourcing of StrongTalk by Sun, including the virtual machine of the fastest Smalltalk implementation .. to all language fanatics, here is the chance to have a look at some of the best innovations in a dynamic language with optional typing. As Gilad says
Apart from speed, it had support for mixins inside the VM, flyweight glyph based UI, optional type system and mirror based reflection, to name a few of the major innovations.


Enjoy !!

Technorati Profile

Thursday, September 07, 2006

Which Web Framework Do You Want to Use Today ?

Yes, it has literally come to this point, where you need to rummage across hundreds of pages to decide upon the technology / framework that you will use in the Web tier. In designing an enterprise application, we had converged upon Struts way back in 2001, since the only other available alternative was to write one ourselves. Things were so simple those days!

Struts - Reunited!

Struts is now like a broken family with a number of subprojects, each trying to carve its way to the mainstream - thanks to some decent heads we may see the light of Struts 2 (aka SAF 2) release very soon. Struts is one of the members in the milieu of action-oriented Web frameworks that still give HTML the respect of being a transaction oriented protocol by offering *Action* as the principal abstraction. But from whatever I have seen of Struts 2 (and their adoption of WebWork codebase), I think it is on its way up to where it belonged a couple of years back. And it also offers integration with all sorts of other frameworks in the world -

  • it uses Spring as the IoC container and has a proposed integration with Spring Web Flow

  • Don Brown has recently announced a JSF integration (the holy grail of unification of action-oriented and component-oriented paradigms) by a clever usage of the Interceptor stack



Spring MVC - Struts 1.x++

Among the other dominant players in the action-oriented world, I like Spring MVC a lot and have really found nothing to complain about it. It offers definite improvements over Struts 1.x wrt the programming model in that it has -

  • a strong data binding and validation mechanism that uses Spring's data binder and validator

  • IoC for easy testing (that's bread and butter for any Spring offering)

  • seamless integration with multiple view technologies

  • the best integration with Spring on earth


I guess the main factor between choosing either of the above 2 will be the developers' expertise that u have on your team. But Struts has a stronger community and a much larger user base that Spring MVC.

Components on the Web - The Java Server Faces

This is the latest standard from Sun and offers the component model for Web frameworks. While the action-oriented frameworks use *actions* to push request into the model and the view, JSF uses components throughout. The entire view is modeled as a tree of components and it is the responsibility of the “ViewHandler” implementation of JSF to create and render the component tree using the underlying view technology (the default is the JSP).

JSF is an attempt to align Web UI tier to the rich client metaphor of desktop applications - I am not very sure if this will scale. HTTP is stateless and having a heavyweight stateful component model plugged in there implies an equally heavy-duty maintenance cycle(state saving and rendering). That's precisely the complaint that we hear for JSF (see here, here and here) and no wonder we find people like Jacob Hookom and Ed Burns desperately trying to get some ways out of this through partial statelessness of the component model, the JSF Avatar Proposal and the other extensions in jsf-extensions.

Till today, JSF has scalability problems for large enterprise applications - the specification is a neat component model with typed event handling, encapsulated markups, separate validators and converters and a well-documented lifecycle. The problem is the implementation, which is a serious roadblock towards scalability of performance. Inspite of all these, JSF may be the platform of the future because of tool friendliness, enhanced support for developer productivity and the backing of the big daddy.

I would not dare to push into a full blown JSF based Web tier in my large scale performance sensitive, clustered enterprise application.

Another close relative in this world of component oriented Web frameworks is Tapestry, hailed by many as technically much superior to JSF. But, Tapestry has a long learning curve, is basically a single man show and has long release cycles with least concern for backwards compatibility.

My Stack

It is quite useful to use a mix-n-match solution stack, since most of the frameworks offer nice integration (a symbiosis of sorts).

  • For stateless pages that need raw speed, I would go for action-oriented frameworks. Whether it is Spring MVC or Struts 2 will depend upon the expertise that my team has. Spring MVC offers more powerful Spring integration (obviously), but Struts has stronger community presence - so it is really a matter of judgement on the spot.

  • For rich component oriented pages only, I would go for JSF and Facelets with backing beans having Spring services injected within, but have the action controller from Struts 2 or Spring MVC. So, JSF usage is limited only for very specific cases which will really benefit from the rich component model.

  • Lastly for dialogs and other flow intensive pages, I would pick up Spring Web Flow, since it is the best in stateful flow management with rich support for continuations (BTW, what's the deal with Struts Flow - the latest download is a 2004 snapshot!). I know SWF integrates with JSF, but I am not very sure about the current state of integration between SWF and Struts 2.


The above stack is pretty heavy and uses multiple frameworks. I have not tried this out (may be I should) - I hope the integration points work out as promised by each party. It will be great to hear from all of you about your recommendation for the Web-tier stack.