In programming, correctness and robustness are two high-level principles from which a number of other principles can be traced back to.

Correctness Robustness
Design by Contract
Defensive programming
Assertions
Invariants
Fail Fast
Populating missing parameters
Sensible defaults
Getting out of the users way
Anticorruption Layer
Backwards-compatible APIs

Robustness adds built-in tolerance for common and non-critical mistakes, while correctness throws an error when it encounters anything less than perfect input. Although they are contradictory, both principles play an important role in most software, so it’s important to know when each is appropriate, and why.

Robustness

“Robustness” is well known as one of the founding principles of the internet, and is probably one of the major contributing factors to its success. Postel’s Law summarizes it simply:

Be conservative in what you do; be liberal in what you accept from others.

Postel’s Law originally referred to other computers on a network, but these days, it can be applied to files, configuration, third party code, other developers, and even users themselves. For example:

Problem Robust approach Correct approach
A rogue web browser that adds trailing whitespace to HTTP headers. Strip whitespace, process request as normal. Return HTTP 400 Bad Request error status to client.
A video file with corrupt frames. Skip over corrupt area to next playable section. Stop playback, raise “Corrupt video file” error.
A config file with lines commented out using the wrong character. Internally recognize most common comment prefixes, ignore them. Terminate on startup with “bad configuration” error.
A user who enters dates in a strange format. Try parsing the string against a number of different date formats. Render the correct format back to the user. Invalid date error.

(Important side note: Postel’s law doesn’t suggest skipping validation entirely, but that errors in non-essential items simply be logged and/or warned about instead of throwing fatal exceptions.)

In many cases, relentless pursuit of correctness results in a pretty bad user experience. One recent annoyance of mine is companies that can’t handle spaces in credit card numbers. Computers are pretty good at text processing, so wasting the user’s time by forcing them to retype their credit card numbers in strange formats is pure laziness on behalf of the developer. Especially if you consider the validation error probably took more code than simply stripping the spaces out.

Compare this to Google Maps, where you can enter just about anything in the search box and it will figure out a street address. I know which I prefer using.

Robustness makes users’ lives easier, and by doing so promotes uptake. Not only amongst end users, but also developers — if you’re developing a standard/library/service/whatever, and can build in a bit of well thought-out flexibility, it’s going to grant a second chance for users with clients that aren’t quite compliant, instead of kicking them out cold.

Adam Bosworth noted a couple of examples of this in a recent post what makes successful standards:

If there is something in HTTP that the receiver doesn’t understand it ignores it. It doesn’t break. If there is something in HTML that the browser doesn’t understand, it ignores it. It doesn’t break. See Postel’s law. Assume the unexpected. False precision is the graveyard of successful standards. XML Schema did very badly in this regard.

HTTP and HTML are displaying robustness here; if they see anything they don’t recognize they simply skip past it. XML Schema on the other hand fails validation if there are any extra elements/attributes present other than precisely those specified in the XSD.

Correctness

So robustness makes life easier for users and third-party developers. But correctness, on the other hand, makes life easier for your developers — instead of bogging down checking/fixing parameters and working around strange edge cases, they can focus on the one single model where all assumptions are guaranteed. Any states outside the main success path can thus be ignored (by failing noisily) — producing code that is briefer, easier to understand, and easier to maintain.

For example, consider parsing XHTML vs regular HTML. If XHTML isn’t well formed, you can simply throw a parser error and give up. HTML on the other hand has thoroughly documented graceful error handling and recovery procedures that you need to implement — much harder than simply validating it as XML.

Which should you use then?

We have a conflict here between robustness or correctness as a guiding principle. I remember one paralyzing moment of indecision I had when I was a bit younger with this very question. The specific details aren’t important, but the 50/50 problem basically boiled down to this: If my code doesn’t technically require this value to be provided, should I check it anyway?

To answer this question, you need to be aware of where you are in the code base, and who it is serving.

  • External interfaces (UI, input files, configuration, API etc) exist primarily to serve users and third parties. Make them robust, and as accommodating as possible, with the expectation that people will input garbage.
  • An application’s internal model (i.e. domain model) should be as simple as possible, and always be in a 100% valid state. Use invariants and assertions to make safe assumptions, and just throw a big fat exception whenever you encounter anything that isn’t right.
  • Protect the internal model from external interfaces with an anti-corruption layer which maps and corrects invalid input where possible, before passing it to the internal model.

Remember if you ignore users’ needs, no one will want to use your software. And if you ignore programmers’ needs, there won’t be any software. So make your external interfaces robust. Make your internal model correct.

Or in other words: internally, seek correctness; externally, seek robustness. A successful application needs both.

February 10th, 2010 | 5 Comments

One of the applications I work on is a planning system, used for managing the operations of the business over the next week, month and financial year.

Almost every entity in this application has a fixed ‘applicable period’ — a lifetime that begins and ends at certain dates. For example:

  • An employee’s applicable period lasts as long as they are employed
  • A business unit’s lifetime lasts from the day it’s formed, to the day it disbands
  • A policy lasts from the day it comes into effect to the day it ends
  • A shift starts at 8am and finishes at 6pm

Previous incarnations of the application simply added StartDate and EndDate properties to every object, and evaluated them ad-hoc as required. This resulted in a lot of code duplication — date and time logic around overlaps, contiguous blocks etc were repeated all over the place.

As we’ve been carving off bounded contexts and reimplementing them using DDD, I’m proud to say this concept has been identified and separated out into an explicit value type with encapsulated behaviour. We call it a Time Period:

It’s sort of like a .NET TimeSpan but represents a specific period of time, e.g. seven days starting from yesterday morning — not seven days in general.

Here’s the behaviour we’ve implemented so far, taking care of things like comparisons and overlapping periods:

/// <summary>
/// A value type to represent a period of time with known end points (as
/// opposed to just a period like a timespan that could happen anytime).
/// The end point of a TimeRange can be infinity.
/// </summary>
public class TimePeriod : IEquatable<TimePeriod>
{
    public DateTime Start { get; }
    public DateTime? End { get; }
    public bool IsInfinite { get; }
    public TimeSpan Duration { get; }
    public bool Includes(DateTime date);
    public bool StartsBefore(TimePeriod other);
    public bool StartsAfter(TimePeriod other);
    public bool EndsBefore(TimePeriod other);
    public bool EndsAfter(TimePeriod other);
    public bool ImmediatelyPrecedes(TimePeriod other);
    public bool ImmediatelyFollows(TimePeriod other);
    public bool Overlaps(TimePeriod other);
    public TimePeriod GetRemainingSlice();
    public TimePeriod GetRemainingSliceAsAt(DateTime when);
    public bool HasPassed();
    public bool HasPassedAsAt(DateTime when);
    public float GetPercentageElapsed();
    public float GetPercentageElapsedAsAt(DateTime when);
}

Encapsulating logic all in one place means we can get rid of all that ugly duplication (DRY), and it still maps cleanly to StartDate/EndDate columns in the database as an NHibernate component or IValueType.

You can grab our initial implementation here:

November 25th, 2009 | 5 Comments

Here’s a snippet of ubiquitous language (altered slightly to protect the innocent) from a system I’ve been working on over the past few months:

An Officer is a role played by certain Employees. Each Officer is required to be proficient in a number of Competencies, according to [among other things] what District they’re stationed in.

We originally implement the Officer-District association as a query because it comes from a different bounded context (Rostering) and changes frequently as Employees move around.

Class diagram with query association

When creating an Officer role for an Employee, we simply queried to find out what District they were working in and what Competencies are required to be practiced there. It looked something like this:

public class OfficerRoleFactory : IRoleFactory&lt;Officer&gt;
{
    ...

    public Officer CreateRoleFor(Employee employee)
    {
        District district = districtResolver.GetCurrentLocationOf(employee);

        var requiredCompetencies = competencyRepository
            .GetCompetenciesRequiredToBePracticedIn(district);

        return new Officer(employee, requiredCompetencies);
    }
}

That was great for when someone first became an Officer, but presented a big problem when they want to move to a different District. To update their required Competencies we have to:

  1. Find what Competencies were required because of their old District
  2. Find what Competencies are required in their new District
  3. Add new required Competencies to the Officer and remove any that no longer apply

Our model did not easily permit this because it failed to encapsulate what District an Officer was working in when their required Competencies were assigned (we simply queried for their current location whenever it was needed). Our code got stuck:

public class Officer : IRole
{
    ...

    /// &lt;summary&gt;
    /// Change the District the Officer is working in. Removes any
    /// Competencies no longer required to be practiced and adds
    /// new ones.
    /// &lt;/summary&gt;
    public void ChangeDistrict(District newDistrict)
    {
        var oldCompetencies = competencyRepository
            .GetCompetenciesRequiredToBePracticedIn(/* what goes here? */);

        var newCompetencies = competencyRepository
            .GetCompetenciesRequiredToBePracticedIn(newDistrict);

       this.requiredCompetencies.Remove(oldCompetencies);
       this.requiredCompetencies.Add(newCompetencies);
    }

}

An Officer’s old District simply wasn’t defined anywhere.

Make everything explicit

Even without updating Competencies to reflect staff movements, we foresaw a lot of confusion for users between where Training thinks you are and where the Rostering says you actually are.

We decided the best way to resolve these issues was to make the Officer-District association a direct property of the Officer that gets persisted within the Training BC:

Class diagram with explicit District property

It seems like a really simple conclusion now, but took us a while to arrive at because our heads were stuck in the rest of the system where pretty much everything (legacy dataset-driven code) queries back to the live Roster tables. Instead we should have been focusing on domain driven design’s goal of eliminating confusion like this by making implicit concepts explicit:

public class Officer : IRole
{
    /// &lt;summary&gt;
    /// The District the Officer is currently stationed in. He/she must
    /// be proficient in Competencies required there.
    /// &lt;/summary&gt;
    public District District { get; set; }

    ...

    /// &lt;summary&gt;
    /// Change the District the Officer is working in. Removes any
    /// Competencies no longer required to be practiced and adds
    /// new ones.
    /// &lt;/summary&gt;
    public void ChangeDistrict(District newDistrict)
    {
        var oldCompetencies = competencyRepository
            .GetCompetenciesRequiredToBePracticedIn(this.District);

        var newCompetencies = competencyRepository
            .GetCompetenciesRequiredToBePracticedIn(newDistrict);

       this.requiredCompetencies.Remove(oldCompetencies);
       this.requiredCompetencies.Add(newCompetencies);

       this.District = newDistrict;
    }

}

Benefits

Refactoring away from the query to simple object composition makes our domain model a lot easier to understand and also improved some SOA concerns and separation between BCs:

  • ‘Where the Training BC thinks you are’ is now an explicit and observable concept. This clears up a lot of confusion both for users wondering why certain Competencies are assigned to them, and developers trying to debug it.
  • It breaks an ugly runtime dependency between the Training and Rostering BCs. Previously, if the DistrictResolver failed for some reason, it would block the Training BC from succeeding because it was called in-line. Now we can take that whole Rostering BC offline and Training won’t notice because it knows for itself where each Officer is stationed.
  • It allows us to deal with staff movements in a much more event-driven manner. Instead of the DistrictResolver returning up-to-the-second results each time, the District is now an explicit property of the Officer aggregate root that only changes when we want it to — e.g. in response to a StaffChangedDistrict domain event. We can now queue these events and achieve better performance via eventual-consistency.

Overall I am very happy with this.

October 26th, 2009 | 2 Comments

Here’s a repository from an application I’ve been working on recently. It has a pretty significant leaky abstraction problem that I shall be fixing tomorrow:

public interface IEmployeeRepository
{
    void Add(Employee employee);
    void Remove(Employee employee);
    void GetById(int id);
    void Save(Employee employee);
}

What’s wrong with this picture?

Let me quote the DDD step by step wiki on what exactly a repository is:

Repositories behave like a collection of an Aggregate Root, and act as a facade between your Domain and your Persistence mechanism.

The Add and Remove methods are cool — they provide the collection semantics. GetById is cool too — it enables the lookup of an entity by a special handle that external parties can use to refer to it.

Save on the other hand signals that an object’s state has changed (dirty), and these changes need to be persisted.

What? Dirty tracking? That’s a persistence concern, nothing to do with the domain. Dirty tracking is the exclusive responsibility of a Unit of Work — an application-level concept that most good ORMs provide for free. Don’t let it leak into your domain model!

October 22nd, 2009 | 8 Comments

A few days ago I read a really great post by Seth Godwin about Traction and Friction. He’s not a programmer (as far as I know), but writes a lot of insightful articles about strategy and value that can be applied to everyday subjects.

This particular article struck a chord in me as a good metaphor for the benefits domain-driven design brings to object-oriented code. Here’s a snippet:

A big car on a wet frozen lake goes nowhere. No traction, no motion.

A small bug working its way across a gravel driveway takes forever. Too much friction, too little motion.

If you’re stuck, it’s probably because one of these two challenges.

The power of online platforms is that they create traction. No, you can’t write more than 140 characters, no you can’t design any layout you want, no you can’t spam everyone with your inane sales pitch. You have something to leverage against, but it’s that thing, the friction, that makes it work.

Object-oriented languages like C# or Java are very powerful things. They provide an infinite canvas on which you can create just about anything, including a huge mess — like the car on the frozen lake — if you start coding without any rules to guide you.

DDD on the other hand provides principles and patterns you can leverage and push off with, like the side of a swimming pool. No you can’t put UI logic in the domain layer, no you can’t use a dataset to model an important business concept, no you can’t reference this entity without going through its aggregate root first. This friction is what makes DDD effective — it gives traction to your OO code.

October 18th, 2009 | No Comments Yet