Sunday, December 7, 2008

ThoughtWorks Cruise: First Impressions

We use CruiseControl.Net as our continuous integration server in our company. CruiseControl.NET is a great tool and helps us a lot in adopting our continuous integration practice. Over the years a lot of cruise control projects accumulated. Currently we have 8 build servers with all together over 100 projects. Most of the time some servers just do nothing while others are under heavy load. So we're looking for a solution to use our hardware more efficiently.

What we really need is a tool that can distribute builds to different machines. Fortunately most of the commercial continuous integration servers do support this kind of feature. Most of them use some sort of a server/agent based concept to distribute builds. Thoughtworks provides a good overview of several CI products that are available on the market. I decided to have a deeper look at Cruise, the enterprise version of Cruise Control from Thoughtworks.

So I downloaded the free edition of Cruise 1.1 and installed it on my laptop. Cruise consists of a server (Cruise Server) and several agents (Cruise agents), that receive work delegated from the server. Therefore a build can be processed in parallel by several cruise agents. What I really liked about Cruise is their implementation of the concept of the deployment pipeline. Cruise allows monitoring of changes to an application as they progress from initial check-in to functional testing, performance testing, user acceptance testing, staging, and release. A pipeline consists of one ore more stages which again consists of jobs. You can consider a pipeline configuration as a workflow of a particular release process. In that way Cruise goes beyond basic continuous integration that many products support these days.

What's interesting is that not every state transition has to be automatically triggered. Some stages may be manually approved before the release process can go further. For instance, in my current project most of the tests are accomplished manually by domain experts outside of the development team. During an iteration or at the end of an iteration we provide builds for manuall testing. In Cruise, this process could be implemented by a stage that needs manual approval.

When I hit Cruise's dashboard for the first time I was disappointed about the few features the product seemed to provide. The main page has just four tabs for viewing the current activity, managing pipelines and agents and a administration tab. Everything looked so minimalistic. But when I begun to use it, I was surprised that most of the things I wanted to do I could do.

But there are some negative points too. In the current version 1.1 they just support Subversion, Mercurial, Git and Perforce for source control integration. There are some other features that are missing in comparison to CruiseControl.NET. There is no support for visualizing reports from tools like FxCop or NCover, just NUnit is supported. They don't provide a plugin mechanism like Cruise Control. So there is currently no contribution or self extension possible.

To summarize, Cruise looks very promising for me. I really liked the concept of pipelines and the minimalistic user interface. From a CruiseControl.NET user perspective there are some key features missing in the current version 1.1. But I'm sure that the agile guys from Thoughtworks will soon come out with a new version that may include those missing features.

Saturday, October 18, 2008

Are Aggregates Practical?

My coworker Jörg Jenni from GARAIO reflects in his recent post on how his team is implementing aggregates. I worked with him and his team for a few months so I know how their current implementation looks like. To be honest I was one of the developers that had problems to follow the rules that come with aggregates.

From Evans, the rules we need to enforce include:
  • The root Entity has global identity and is responsible for checking invariants
  • Root Entities have global identity. Entities inside the boundary have local identity, unique only within the Aggregate.
  • Nothing outside the Aggregate boundary can hold a reference to anything inside, except to the root Entity.
  • Objects within the Aggregate can hold references to other Aggregate roots.
  • A delete operation must remove everything within the Aggregate boundary all at once
  • When a change to any object within the Aggregate boundary is committed, all invariants of the whole Aggregate must be satisfied.
Especially the "do not hold a reference from the outside to an object inside the aggregate" rule is very strict. Jörg suggests in his post to implement aggregate internals as private classes in the root class. With this approach sure you will not violate the rule anymore as the compiler enforces it. The problem is that at some point you will need access to these objects even if they are identified as conceptually internal. For example as a client I need a reference to these internals to show some information on a screen, to test the logic of the internal object or to execute some business logic that needs knowledge of data and behavior of objects in the aggregate.

Don't understand me wrong, I really would love to apply this pattern. The essence of aggregates to identify a cluster of objects that can be conceptually thought of as one unit is very important for managing complexity. But is it practical in our today's programming model? On the domain driven design discussion board I found an interesting discussion about aggregate boundaries between DDD adopters and Eric Evans. From the discussion I see that we're not the only ones that have problems with the implementation of aggregates. And what's interesting is that in the same discussion Mr. Evans wrote that he'll try to add a concrete example and that he we'll come up with some useful new insight - he didn't return to the discussion.

Does anybody has a real world example of aggregates? One that enforces all the rules?

Saturday, September 27, 2008

Let's Do Practices

This week Ivar Jacobson gave a talk at the Microsoft Regional Architect Forum in Zurich. Ivar Jacobson is one of the founders of UML, RUP and use cases. In his talk "Getting Good Software, Quickly and at Low Cost" he spoke about his practiced-based approach to software development. At the beginning he mentioned the main problems of software processes. According to him every process tries to be complete, process documentation is never read and the way how people live the process is soon out of sync with the original process definition. He then suggested a more practice oriented approach for finding the right process. He described what a practice is and how practices can be composed to build custom processes.

The ideas he talked about made a lot of sense to me. I was very surprised by the lightweightness of his approach. As an example he proposed to document a practice by a set of index cards on which you only describe the essentials of the practice.

He also talked about agile software development. For him Agile is "a box" of the good stuff that existed since many years with some social additions. He sees SCRUM as a practice to project management. I always saw SCRUM as a process. But I think his right. It's a good way to do project management in the field of software development. But with SCRUM alone you don't deliver good software. To be successful you'll need good engineering practices, testing practices and other practices for capturing requirements or releasing software. I focused very much on SCRUM for some time now. Together with my fellows we put a lot of effort in adopting SCRUM for the projects we where involved and also for the company wide adoption of SCRUM. Maybe its time for me, to address some other things. Back to good old engineering stuff. There are a lot of practices to explore over at Ivar Jacobson International and also from the Eclipse Process Framework.

Sunday, July 20, 2008

Linq To Sql and Value Objects

Unfortunately Linq to SQL lacks support for Value Objects. This is a big limitation when you do Domain Driven Design as we do it on a project that I'm currently involved. We didn't use this pattern so far but last week there was no way around it. I had to implement a feature based on the stock of monetary units. I identified an object MonetaryUnitStock that represents the stock for a monetary unit like e.g. 10 Swiss francs. I didn't want to care about identity for that object and I wanted it to be immutable.

For my mentioned feature I had no requirements for querying. So the implementation with Linq to SQL was straight forward. Here is the code in C#.

public struct MonetaryUnitStock: IEquatable<MonetaryUnitStock>
{
private readonly int _numberOfUnit;
private readonly MonetaryUnitType _type;

public MonetaryUnitStock(MonetaryUnitType type, int numberOfUnit)
{
_type = type;
_numberOfUnit = numberOfUnit;
}

public int NumberOfUnit
{
get { return _numberOfUnit; }
}

public MonetaryUnitType MonetaryUnitType
{
get { return _type; }
}

public bool Equals(MonetaryUnitStock other)
{
return MonetaryUnitType.Equals(other.MonetaryUnitType) && this.NumberOfUnit.Equals(other.NumberOfUnit);
}

public override bool Equals(object obj)
{
if(obj is MonetaryUnitStock)
{
return Equals((MonetaryUnitStock)obj);
}
return false;
}


public override int GetHashCode()
{
return MonetaryUnitType.GetHashCode() ^ NumberOfUnit.GetHashCode();
}
}

    partial class MoneyList
{
private MonetaryUnitStock? _monetaryUnitStockUnit100;

public MonetaryUnitStock MonetaryUnitStockUnit100
{
get
{
if (_monetaryUnitStockUnit100 == null)
{
_monetaryUnitStockUnit100 = new MonetaryUnitStock(MonetaryUnitType.Unit100, NumberOfUnit100);
}
return _monetaryUnitStockUnit100.Value;
}
set
{
if(value.MonetaryUnitType != MonetaryUnitType.Unit100)
{
throw new ArgumentException("MonetaryUnitStockUnit100 expects MonetaryUnitType.Unit100");
}
_monetaryUnitStockUnit100 = value;
_NumberOfUnit100 = _monetaryUnitStockUnit100.Value.NumberOfUnit;
}
}
}


I used the DBML designer for creating this simplified example. In the designer I marked the NumberOfUnit100 attribute as private to just provide the Value Object to the outside. So client just can set and get MonetaryUnitStockUnit100 and have no access to the underlying simple type.

The reason that I implemented the MonetaryUnitStockUnit100 Property with lazy loading is, that Linq to SQL provides no interception point when reconstituting an object from persistence. The OnCreated() method generated by the designer is not suitable as it is called before the actual values are set.

Monday, March 24, 2008

Using LINQ with Text Files

I'm currently reading the book LINQ in Action which I can highly recommend to all who want to get started with LINQ. In one of the first chapters there is a nice example on how you can use LINQ with text files (originally posted by Eric White). Rather than reading all lines of the file into memory and then query it, the example uses deferred execution with an extension method on the class StreamReader.

Inspired by this example I wrote a simple file reader that can read structured non-XML data from text files. As you can see in the Process method in the code below the text file is queried and processed line by line. Objects are created on the fly, as you loop through the results. This technique allows you to work even with huge files.

public class RecordReader{
private Dictionary<string, IReaderStrategy> _strategies = new Dictionary<string, IReaderStrategy>();
private const char Comment = '#';
private int _typeFieldLength;

public RecordReader(int typeFieldLength)
{
_typeFieldLength = typeFieldLength;
}

public IList Process(StreamReader input)
{
var result =
from line in input.Lines()
where !IsBlank(line)
where !IsComment(line)
select GetStrategy(line).Process(line);
return result.ToList();
}

private IReaderStrategy GetStrategy(string line)
{
string typeCode = GetTypeCode(line);
if(!_strategies.ContainsKey(typeCode))
{
throw new NoStrategyDefinedException("No strategy defined for code " + typeCode);
}
return _strategies[typeCode];
}

private static bool IsComment(string line)
{
return line[0] == Comment;
}

private static bool IsBlank(string line)
{
return string.IsNullOrEmpty(line);
}

private string GetTypeCode(string line)
{
return line.Substring(0, _typeFieldLength);
}

public void AddStrategy(IReaderStrategy arg)
{
_strategies[arg.Code] = arg;
}
}

You can download the full source code from here

Wednesday, January 30, 2008

Unit Testing Legacy Code

After my short HTML/CSS intermezzo I'm back to the business logic programming. Even though it was instructive to do web design and presentation logic I'm happy that I can dive into the lower layers now. With this change I can also switch to my preferred way of developing software, which means TDD.

Everyone who ever wanted to do TDD in a code base that was not designed for testability knows how hard it is. The hardest part is certainly to break dependencies so you can unit test a class or method in isolation. In my last project I was involved we had quite a large code base before we started to write unit tests. With the support of Typemock we could work around the untestable pieces and TDD got possible.

Unfortunately I can't use Typemock on my current project. So I have to get back to other techniques that I learned from "Working Effectively with Legacy Code" by Michael Feathers. Here are the techniques I use a lot:

  • Subclass and Override Method. Create a subclass of the class and override the method to break the dependency.
  • Break out Method Object. Perhaps you can't get a method under test. Create a new class with the method under test.
  • Sometimes it's not possible to create an instance of an object because there are too many dependencies. Expose the method under test as a static method so it's easier to test.
  • Expose private Method. To access a private method from your fixture subclass the class and expose the method.
Even though its a little bit more work in comparison of using Typemock I think the use of these techniques results in more readable test code.