I am going to get sued for temporal harassment

time to read 10 min | 1968 words

Go read the title again, first. It is not what you think.

I mentioned before that I am working on temporal system. Actually, it didn't start as temporal system. It started as you everyday business system. Fairly complex domain, very interesting problems. At the time, I had Evan's DDD heavy on my mind, and I had a really nice domain model that I could work with.

Just to make a point, the code I am going to show is a very simple piece of code, meant to sort a list of employee's contracts by their name.

Using this domain model, I could sort the contracts list like this:

Algorithms.SortInPlace(templates, delegate(ContractTemplate x, ContractTemplate y)

{

      return x.Name.CompareTo(y.Name);

});

Very simple to grok, using Power Collections to make this even nicer.

Then the Change Request came*. All objects in the system are time bound and may have multiply occurances. What does this mean? It means that I can no longer ask a contract for any of its properties. I need to ask it for its properties at a certain point in time. That was a fairly big change, and I handled it using this approach. This meant that I had to go on all my code and change each property access to use the relevant date. Naturally, I mostly used DateTime.Today. so the above code turned into this:

Algorithms.SortInPlace(templates, delegate(ContractTemplate x, ContractTemplate y)

{

      return x.At(DateTime.Today).Name.CompareTo(y.At(DateTime.Today).Name);

});

But here is the kicker, in temporal systems, one of the key elements is the time that you are looking at the system vs. the time of the objects. This mean that I can very well look at an object that doesn't exist at this point in time.

To make this more obvious, consider the following case. I am currently looking at a list of employees as it was three years ago. Obviously, any new employees do not exists in the list, even though they are on the system. The way I implemented this approach is simply throwing exception when you ask an object for its state at a date where it didn't exist.

So, we are happily developing the system and trying to understand our code through 9 levels of different date intervals. But, we show the system to the customer, and the first thing that they do is to create an object in the future and then try to view its state today. If you consider the case, you will see that of course it throws an exception. The problem is how to deal with it. Here is the current code to sort a list of contracts by their names:

Dictionary<Employee, ContractTemplate > employeeAndContracts = ...;

templates = Algorithms.Sort(employeeAndContracts, delegate(ContractTemplate x, ContractTemplate y)

{

   DateTime y_maybeValidDateToCheck = employeeAndContracts [y].Employement.Start;

   DateTime x_maybeValidDateToCheck = employeeAndContracts [x]. Employement.Start;

   if (x.Validity.Overlap(x_maybeValidDateToCheck) == false)

   {

       if (y.Validity.Overlap(y_maybeValidDateToCheck) == false)

           return 0;

       else

           return -1;

   }

   string name_x = x.At(x_maybeValidDateToCheck).Name;

   if (y.Validity.Overlap(y_maybeValidDateToCheck) == false)

       return 1;

   string name_y = y.At(y_maybeValidDateToCheck).Name;

   return name _x.CompareTo(name _y);

});

Yes , I did refactored it out to a method, but the sheer complexity of doing a simple sort is annoying. You can imagine the complexity of working with the model on a day to day basis and why I dislike System.DateTime so much...

* One important thing to mention, because of disclosure issues, I am not talking about the actual system, but a parallel one, which I can talk about safely. This is relevant here because the temporal decision is not an obvious one in this system, while employee's contracts is usually the classic place for this type of system.