var blog = new ThoughtStream(me); RSS 2.0
 Wednesday, November 26, 2008

In the comments of my previous post - Descriptive State Enumeration - Maxim Tihobrazov asked me to show how to map a state pattern with NHibernate; and I am more than happy to oblige!

NHibernate Mapping Options

I certainly don't claim to be an expert on NHibernate, but I do use it on a daily basis and I've solved my fair share of problems - including how to map a State pattern with NHibernate. According the NHibernate inheritance documentation, there are three core ways of mapping this pattern:

  1. Table per class hierarchy (I've always called it "record per class") - each subclass (state instance, in this case) is associated with a specific record in a table. All of the subclasses are found in the same table.
  2. Table per subclass (also called a "joined sub class") - each sub class has it's own table and is joined to the super class by a one to one relationship with it's primary key.
  3. Table per concrete class - each sub class has it's own table and is mapped by the specific class type, not by the abstraction.

My Choice - Table Per Class Hierarchy

In my current set of applications, I've always used the table per class hierarchy option so that is what I will describe here. My reasons for choosing this option are simplicity in the mapping and more importantly - not having a need to store the records in their own tables. Each of my states can be very cleanly represented as a record in my state table.

Setting Up Shop

Let's consider the same coffee shop that I've used in both of my PTOM posts - in this case, we're dealing specifically with the Order class and it's OrderStatus state. It's necessary to note that when I am working with NHibernate and the state pattern, I actually do set up my state models a little different. First off - we need an Id for NHibernate to map to the table's primary key. Secondly, I like to keep the core information in the abstract base class and provide all the varying values via a constructor. Third, each of the inheriting classes needs to provide a default (no args) constructor. Forth, we need a way for NHibernate to know which class it should actually instantiate, when loading - a "descriminator". I like to use a simple string Name property for this. And lastly - I think (though I am likely wrong on this aspect) that the abstract base class needs to provide a default constructor. Fortunately, the constructors we need don't need to be public - they can be private.

With all of that being said, here is realistic code base that I would use for my Order and OrderStatus model:

public class Order
{
   public int Id { get; set; }
   public OrderStatus Status { get; set; }
}
 
public abstract class OrderStatus
{
   public static InProcess = new InProcessStatus();
   public static Totaled = new TotaledStatus();
   public static Tendered = new TenderedStatus();
   public static Delivered = new DeliveredStatus();
 
   public int Id { get; set; }
   public bool DisplayForFullfillment { get; }
   public string Name { get; set; }
 
   private OrderStatus() { }
 
   private OrderStatus(int id, bool display, string name)
   {
       Id = id;
       DisplayForFullfillment = display;
       Name = name;
   }
}
 
public class InProcessStatus: OrderStatus
{
   private InProcessStatus(): base(1, false, "InProcess");
}
 
public class TotaledStatus: OrderStatus
{
   private TotaledStatus(): base(2, true, "Totaled");
}
 
public class TenderedStatus: OrderStatus
{
   private TenderedStatus(): base(3, true, "Tendered");
}
 
public class DeliveredStatus: OrderStatus
{
   private DeliveredStatus(): base(4, false, "Delivered");
}

The Fluent NHibernate Maps

I'm a huge fan of Fluent NHibernate. I've been using it since just after it was branched from the original ShadeTree code. And at one point, I had submitted so many patches that I was made a comitter on the project. So, it should be no surprise to anyone that I'm going to advocate using FluentNHibernate over the .hbm.xml mapping files. Truth be told, I don't even remember how to do the needed descriminators in hbm.xml files. There was some trick to the descriminator being the first specified items after the Id or something... it's just easier to do in FluentNHibernate, so I don't bother with hbm.xml files anymore.

The Order map is going to be as standard as any other map. You don't need to do anything special here. Just map the Id of the Order and the referenced OrderStatus. (I like to add a "CreateMap()" method that is called from the constructor, so that I can avoid the "virtual method call from a constructor" warning. But I also use the "treat warnings as errors" option for my C# projects).

public class OrderMap: ClassMap<Order>
{
   public OrderMap()
   {
       CreateMap();
   }
 
   public void CreateMap()
   {
       DefaultAccess.AsProperty();
       WithTable("Orders");
       Id(o => o.Id).GeneratedBy.Assigned();
   }
}

It's really the OrderStatus map that is special in this case. This is where we get into the details of the descriminator - telling NHibernate which specific instance to create, when loading the data from the database. In our case, we have added a "Name" field to our OrderStatus object and we will be explicitly using this property as the descriminator.

public class OrderStatusMap: ClassMap<OrderStatus>
{
   public OrderStatusMap()
   {
       CreateMap();
   }
 
   public void CreateMap()
   {
       DefaultAccess.AsProperty();
       WithTable("OrderStates");
       Id(s => s.Id).GeneratedBy.Assigned();
 
       DiscriminateSubClassesOnColumn<string>("Name")
 
           .SubClass<InProcessStatus>()
               .IsIdentifiedBy(OrderStatus.InProcess.Name)
               .MapSubClassColumns(x => { })
 
           .SubClass<TotaledStatus>()
               .IsIdentifiedBy(OrderStatus.Totaled.Name)
               .MapSubClassColumns(x => { })
 
           .SubClass<TenderedStatus>()
               .IsIdentifiedBy(OrderStatus.Tendered.Name)
               .MapSubClassColumns(x => { })
 
           .SubClass<DeliveredStatus>()
               .IsIdentifiedBy(OrderStatus.Delivered.Name)
               .MapSubClassColumns(x => { })
 
       Map(s => s.Name);    
   }
}

The key to all of this is the DescriminateSubClassesOnColumn method. The generics <string> tells us what .NET Type is being used to identify the specific class instances that we are dealing with and the ("Name") parameter is the column name in the database that represents the specific instance.

Then, we have the specific class instances referenced by the ".Subclass<type>" calls. This is a fluent interface, so ".Subclass" is a method that gets called directly off the DescriminatoeSubClassesOnColumn method. The specific type we want NHibernate to know about is specified in the generics parameter: ".SubClass<InProcessStatus>". The "IsIdentifiedBy" is where we give NHibernate the knowledge of what value in the "Name" column maps to what specific class in our code. To prevent magic string syndrome from setting in, I like to use the actual enumeration pattern of my OrderStatus to specify the string name of the class.

And finally, we have to provide an ugly workaround for our maps via the "MapSubclassColumns" method. There is an implementation issue in FluentNHibernate currently, and because of this issue we are forced to call the "MapSubclassColumns" method, with an empty lambda expression. If we don't call this method, the sub class will not get registered and NHibernate will not know how to handle the data in question. (I am hoping to fix this issue at some time, and make it so we don't have to call that method. I just haven't had time recently.)

Wrapping Up The Map

The rest of the map (the one remaining "name" property being mapped, in this case) is a regular NHibernate map. You'll notice, though, that we never mapped the "DispalyForFullfillment" property. I explicitly choose to leave any and all "volatile" properties out of my state maps. By doing this, I am able to add, edit, and remove any properties or methods on the state objects that I need, without having to change the NHibernate mappings. Since the state objects I am dealing with don't change without recompiling the code anyway, I don't need the ability to define them in the database. However, if you do need or want the flexibility of defining your states in the database, you can map each individual property of the state. Just remember that you will have to modify both the code and the database, to make the changes complete.

I hope this quick look at mapping a state pattern with Fluent NHibernate will help to shed some light on the subject, for someone. I realize that I have only provided the FluentNHibernate mapping, though. I specifically chose to do this because it would be a serious chore for myself to create a code project with NHibernate set up so that I can actually verify my mapping xml is correct. However, the translation from FluentNHibernate back to standard .hbm.xml files should be fairly straightforward, with the help of the NHibernate Documentation. If anyone out there is willing to help out and send me the correct .hbm.xml mapping, I would be more than happy to add it to this post and credit you with the work.



_________________________________
Cross Posted From LostTechies.com
Wednesday, November 26, 2008 10:42:11 PM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: .NET | Data Access | Design Patterns | Lambda Expressions | NHibernate | Principles and Patterns

This post is part of the November 2008 Pablo's Topic Of The Month (PTOM) - Design Patterns and will primarily outline the State pattern, with an Enumeration or Descriptor pattern thrown in for good measure.

Switch statements and if-then statements are not object oriented code. They are conditional logic for procedural control and processing. This doesn't mean that they are bad - by no means. It only means that they are not object oriented. There are many legitimate reasons for using if-then statements and a few legitimate reasons for using switch statements. However, there are also many bad reasons for using these statements.

Setting Up Shop

Before we get into the guts of the State pattern, let's consider the Point of Sale system of our coffee shop again. When a customer is placing an order, we need to track what they are ordering. This would likely be done through an Order object. While the customer is placing their order, the order is considered "in process". Once the customer is done with their order, the cashier can "total" the order. Then, the order is "tendered" (paid for). And finally, the order is "delivered" to the customer. Each of these quoted items is a state that the order goes through during it's brief run through the coffee shop. In C#, it would be very easy to represent these states with a simple enum:

public enum OrderStatus
{
   InProcess = 0,
   Totaled = 1,
   Tendered = 2,
   Delivered = 3
}

With this enum in hand, we can have our point of sale system set the correct order status according to what is going on at the moment.

//when a coffee is ordered
Product regularCoffee = new Product("RegularCoffee", 2.99);
Order order = new Order();
order.Add(regularCoffee);
order.Status = OrderStatus.InProcess;
 
 
//when an order is totaled
double total = order.GetTotal();
order.Status = OrderStatus.Totaled;
 
 
//when the customer pays for the order
order.AmmountPaid = ammountPaidByCustomer;
order.Status = OrderStatus.Tendered;
 
 
//and finally, the order is delivered
order.Status = OrderStatus.Delivered;

Now this code we have so far is technically correct - it works and it gets the job done. Unfortunately, though, this code will likely lead us down a bunch of dark paths of code duplication, ugly switch statements, and an unmaintainable mess. For example, what happens when we start integration our Order object into the rest of the coffee shop and we need to display orders to fulfill on a screen for the order runners to fill. In such a case, we only want to show orders that have been tendered but not delivered, and to try and get orders out the door faster, we'll also show orders that are totaled.  If we were going to examine a single order to determine whether or not we wanted to show it, we would likely have one of the two following pieces of code in place (yes, I know this could be done with a database query. The point is that somewhere in the code you will likely end up with switch statements or if-then statements like this):

//one way to know
bool shouldShowOrder = false;
if (order.Status == OrderStatus.Totaled || order.Status == OrderStatus.Tendered)
     shouldShowOrder = true;
 
//another way to know
bool shouldShowOrder;
switch (order.Status)
{
   case OrderStatus.Totaled:
   {
       shouldShowOrder = true;
       break;
   }
   case OrderStatus.Tendered:
   {
       shouldShowOrder = true;
       break;
   }
   default:
   {
       shouldShowOrder = false;
   }
}
 
//after we know, we show it
if (shouldShowOrder)
     ShowTheOrderForFulfillment(order);

So - what happens when the order status list change? Or if we now have a need to show a different order status on our display? We would have to find all of the locations that used this status enum and check to see if it needs to be changed, to handle the new status or change in how the status is handled. This is where the problems really start - hoping that you got all of the uses changed and all of the right states handled in the right ways. Fortunately, there's a design pattern that we can use to simplify this situation and eliminate many of the associated switch and complex if-then statements.

The State Pattern

Image:State Design Pattern UML Class Diagram.png

 

Wikipedia describes the State Pattern as "a clean way for an object to partially change its type at runtime." The C2 Wiki gives a little more insight into the State Pattern, as well: "Allow an object to alter its behavior when its internal state changes. The object will appear to change its class."

What both of these descriptions are really getting at, is that a single concept in the real world is likely going to be modeled as more than one class in code - composed of many different pieces. When any one part of a concepts model changes, the state of that concept is changed. The relationship between our Order class and OrderStatus enum are a prime example of this composition. What the state pattern allows us to do is change the behavior of our modeled concept by partially changing the composition of our model.

Modeling Our State As State Model

To model the state of our Order with a state pattern instead of a state enum, and begin introducing the ability to change our systems behavior without changing the code that relies on the state, we need to introduce an abstraction that can represent any state we care about. To start with, we need to know what orders should be shown on our display for the order runners.

public interface IOrderStatus
{
   bool DisplayForFulfillment { get; }
}

After introducing this abstraction, we can introduce any state implementation that we need.

public class InProcessStatus: IOrderStatus
{
   public bool DisplayForFullfillment { get { return false; } }
}
 
public class TotaledStatus: IOrderStatus
{
   public bool DisplayForFullfillment { get { return true; } }
}
 
public class TenderedStatus: IOrderStatus
{
   public bool DisplayForFullfillment { get { return true; } }
}
 
public class DeliveredStatus: IOrderStatus
{
   public bool DisplayForFullfillment { get { return false; } }
}

Once we have these states in place, we can replace our code that sets the state with these objects.

double total = order.GetTotal();
order.Status = new TotaledStatus();

And we can also significantly reduce the code that needs to know if we should display this order in our order display system. Now, instead of having to do those if-then or switch statements, we can simply check the order status:

//the order class now relies on the IOrderStatus for it's composition
public class Order
{
   public IOrderStatus Status { get; set; }
}

Yes, we are still using an if-then statement. However, this one simple statement is no longer an issue in terms of maintainability. We don't have to change this code as we add, remove, or change the states of our system. Since we only depend on the IOrderStatus interface for our composition now, we can freely change the implementation of the states as we need - change the composition of the Order's model.

But Wait! There's More!

We don't have to stop at simple boolean values on our state abstraction - we can provide actual behavior via methods in our state. And the best part is - when we can add and remove any behavior or boolean values, or whatever else we need to change with the state of our Order, we don't have to change any of the existing code that uses the existing DisplayForFullfillment value. This property is defined on the interface, letting us use it where we need it and ignore it where we don't need it.

By using a state pattern, as we've seen here, we have introduced the ability to change the behavior of our system without having to change the places that need to know about the state of the order. We've gained a great level of encapsulation. We've gained flexibility in changing states when we need to - and we have an abstraction that hides the details when we don't need them. Seems like a winning situation to me.

But Wait! There's Still More!

Unfortunately, one thing we lose is the friendly syntax of our enumeration. For example, "OrderStatus.Totaled." Personally - I like the simplicity that enumerations offer us in our code. Something about saying "OrderStatus.Totaled" seems to be right to me. So how do we marry the state pattern to the enumeration syntax? The answer is simple - an Enumeration pattern (also called a Descriptor pattern).

We can make a simple change to our order status abstraction - make it an abstract base class. Then we can provide some static fields to provide access to the class instances that we want. To enforce the enumeration like syntax, we can also make the constructor private.

public abstract class OrderStatus
{
   public static InProcess = new InProcessStatus();
   public static Totaled = new TotaledStatus();
   public static Tendered = new TenderedStatus();
   public static Delivered = new DeliveredStatus();
 
   public abstract DisplayForFullfillment { get; }
   private OrderStatus() { }
}
 
public class InProcessStatus: OrderStatus
{
   public bool DisplayForFullfillment { get { return false; } }
}
 
public class TotaledStatus: OrderStatus
{
   public bool DisplayForFullfillment { get { return true; } }
}
 
public class TenderedStatus: OrderStatus
{
   public bool DisplayForFullfillment { get { return true; } }
}
 
public class DeliveredStatus: OrderStatus
{
   public bool DisplayForFullfillment { get { return false; } }
}
 
 
//the order class now relies on the OrderStatus base class for it's composition
public class Order
{
   public OrderStatus Status { get; set; }
}

And now we have our nice friendly enumeration syntax back!