Rediscovering Business Benefits

June 5th, 2008  |  Published in Agile, Behaviour-Driven Development by Ian Robinson

Outcomes and the business value that we’re seeking to release in pursuing those outcomes all too often get passed over in favour of a morass of implementation trivia.

Desired business outcomes frame the delivery of application functionality, or more generally, service capabilities: they motivate software development. The outcome-driven bias of agile practices is reflected in the user story: in the Role-Feature-Benefit story sequence (see Dan North’s What‘s in a story for a description of these parts, and more recently Elizabeth Keogh’s RIP As a… I want… So that… for a compelling reformulation of the story format).

Sadly, many instances of stories try and get by without capturing outcomes and benefits. As one of the commentators on Elizabeth’s post notes: “the ‘so that’s’ are always the hardest thing to write in a story and are the first thing to be omitted.”

I see a lot of stories that neglect Role-Feature-Benefit in favour of the much easier Role-How-Feature. That is: as a <role> I want <something doing this way> so that <I can do this/this happens>:

As a user I want to export results so that I can share them with colleagues

Well, thanks for telling me how to do my job, and not telling me anything about what motivates yours.

Have we specified an outcome here? Not really. What we do have is a misplaced feature masquerading as an outcome, and a pre-emptive description of how to implement that feature. We’ve shuffled the desired outcome, the goal that motivates this feature, off the table. And by pre-emptively specifying an implementation, we’ve limited the opportunity for choosing between several implementation strategies – lo-fi, hi-fi – come implementation time.

When I spot stories like this, I try to “force” the issue of outcomes and benefits by performing a “shift left” on the story parts. Role stays the same, Feature shifts left, and squeezes How out. This leaves: as a <role> I want <to do this/this to happen> so that <??????>:

As a user I want share results with colleagues so that…

Now we’ve got a role, and a feature, and can start asking “why?” regarding the benefit:

As a user I want share results with colleagues so we can make an informed group decision about recent performance

Identifying the benefit allows us to turn the effort dial up and down. You need to do this, urgently? How about this workaround? Estimate: zip.

Atom   RSS 2.0   Email

Linq to Sql (Some Puzzles)

May 19th, 2008  |  Published in Linq by Ian Robinson

I’m currently trying to use Linq to SQL to model and persist some very simple domain objects. Not having used Linq to SQL before, I’m muddling through, but have quickly run up against a couple of things that have me puzzled:

  • Entity classes require a public default constructor
  • There’s no support for user-defined value types

My ignorance? Limitations in the framework? You tell me.

Default Public Constructors for Entity Classes

I’m attributing my entity (domain) classes with TableAttribute, and their members with ColumnAttribute. TableAttribute maps a class to a table in the database; ColumnAttribute maps its members to the table’s columns.

To ensure that an object behaves as a good citizen from the moment it’s instantiated, I prefer to set up its state in its constructor. To further guarantee an object can’t be created in an ill-formed state, I tend not to include a default, parameterless constructor for such classes.

Now unless I’m mistaken, I can’t define a Linq to SQL entity class that lacks a public default constructor:

System.InvalidOperationException: The type 'xxx' must declare a default (parameterless) constructor in order to be constructed during mapping.

Nor can I use a private parameterless constructor:

System.MissingMethodException: No parameterless constructor defined for this object.

I can make my members private, so that only Linq can call the setters during object initialisation, which is great; but I can’t make the constructor private or otherwise accessible only to Linq. Seemingly a small issue, but it means that some objects could end up being created in an invalid state.

No Support for User-Defined Value Types

As far as I’m aware, Linq to SQL doesn’t support user-defined value types. Value types are types that lack identity, much as an integer doesn’t have any identity: this 3 is as good as that 3. Value types serve as attributes of entities - which do possess identity. In a database, value types are often stored in the table of the entity that owns them; in an object model, they’re usually surfaced as a dependent object of the parent class they help describe.

To illustrate what I mean by value type, imagine we are modelling a Picture with Description, Border Thickness and Border Style attributes. We might store the Picture in the database like this:

Picture entity: database schema

- but represent it in code like this:

Picture entity: OO model

Here the Border class constitutes a user-defined value type.

One of the things I want to do with one of my domain objects is store a hash of a string member (a Uri in this instance) with that object’s corresponding database record. I can then index the hash, and lookup records based on the hash rather than a long (500) nvarchar value (which in any case can’t be indexed because it exceeds 900 bytes).

The hashing algorithm isn’t a concern of the entity class that exposes the hash value, so I’ve encapsulated the algorithm in a separate class, effectively making it a user-defined value object:

public class UriHash
{
    private readonly int value;

    public UriHash(string uri)
    {
        value = uri.GetHashCode();
    }

    public UriHash(int value)
    {
        this.value = value;
    }

    public int Value
    {
        get { return value; }
    }
}

As you can see, I’m simply calling GetHashCode() on the relevant string member, but it may be that in the near future I’ll want to change this to use, say, an MD5 hash. When (if) that happens, I’ll have to make changes in several places: in the database schema (int to nvarchar), and in any code that gets or sets an int value. What I’m keen to do, even from the outset, is maintain my encapsulation of the hashing algorithm, but at the same time keep to a minimum the number of places where knowledge of the hash type (int versus string/nvarchar) is baked into the code.

Because Linq to SQL doesn’t currently support user-defined value types, my entity class exposes the hash as a plain old int, as follows:

[Table(Name = "MonitorableResource")]
public class MonitorableResource
{
    // Constructors omitted

    private UriHash uriHash;

    [Column(DbType = "Int NOT NULL", CanBeNull = false)]
    internal int UriHash
    {
        private set { uriHash = new UriHash(value); }
        get
        {
            if (uriHash == null)
            {
                uriHash = new UriHash(Uri);
            }
            return uriHash.Value;
        }
    }

    [Column(DbType = "NVarChar(500) NOT NULL", CanBeNull = false)]
    public string Uri { get; private set; }

    // Other code omitted
}

The problem here is that whilst the hashing algorithm is nicely encapsulated in the UriHash class, the hash type (an int in this instance) is smeared all over the code. The database schema knows it’s an int, and so does the UriHash class. That’s fine: there’s a one-to-one mapping between the OO and the relational worlds. But on top of that, MonitorableResource knows that the type is an int, and that its UriHash member maps to the UriHash column in the database. That’s one place too many for my liking.

Ideally I’d like to expose the MonitorableResource’s UriHash member as a UriHash, and push the ColumnAttribute mapping onto the UriHash type’s Value member - something like this (note, this code isn’t valid Linq to SQL):

[Table(Name = "MonitorableResource")]
public class MonitorableResource
{
    // Constructors omitted

    private UriHash uriHash;

    [ValueObject]
    internal UriHash UriHash
    {
        private set { uriHash = value; }
        get
        {
            if (uriHash == null)
            {
                uriHash = new UriHash(Uri);
            }
            return uriHash;
        }
    }

    [Column(DbType = "NVarChar(500) NOT NULL", CanBeNull = false)]
    public string Uri { get; private set; }

    // Other code omitted
}

public class UriHash
{
    public UriHash() {}

    public UriHash(string uri)
    {
        Value = uri.GetHashCode();
    }

    public UriHash(int value)
    {
        Value = value;
    }

    [Column(Name = "UriHash", DbType = "NVarChar(500) NOT NULL", CanBeNull = false)]
    public int Value { get; set; }
}

Interestingly, the forthcoming Entity Framework does support value objects, which it calls Complex Type Objects. NHibernate, of course, has long supported custom value types.

Atom   RSS 2.0   Email

In Conversation

April 24th, 2008  |  Published in Consumer-Driven Contracts by Ian Robinson

You’d be forgiven for thinking I’ve got nothing else to talk about…

In preparation for the launch of the ThoughtWorks Anthology, each of the authors recorded a short podcast in which they discuss their essay. Mine is online now. It’s four minutes tops - the perfect aural companion as you huddle outside with a cigarette.

If you like that, you might like this: a couple of years ago, Martin Fowler and I did an interview with Microsoft’s Ron Jacobs on the Evolution of Architecture. As per usual, I’m a one-note band…

Atom   RSS 2.0   Email

A Contract Vocabulary: Part 3

April 20th, 2008  |  Published in Consumer-Driven Contracts by Ian Robinson

This is the last of a three-part series of posts discussing the contract vocabulary aspects of my article Consumer-Driven Contracts. The other posts are here:

In this post I’m going to address a few questions and puzzles:

  • Does Consumer-Driven Contracts really achieve a separation of concerns?
  • Are consumer-driven contracts applicable only in point-to-point scenarios?
  • Never mind the theory, is all this feasible in practice?

A Separation of Concerns?

Is the triumvirate of provider, consumer and consumer-driven contracts a true separation of concerns? The goal of any separation of concerns is to allow functions [to] be optimized independently of other functions. Mark Baker suggests that we will have successfully separated concerns if variations in [concern] A do not induce or require a corresponding change in [concern] B (and usually, the converse). Do our three contracts pass this test?

By distinguishing between provider and consumer contracts we make explicit the fact that one half of the provider-consumer relationship ought to be able to change without inducing a corresponding change in the other half – within limits. Providers ought to be able to evolve their contracts without obliging their consumers to change – just so long as they continue to satisfy existing obligations. Consumers ought to be able to modify their consumption of a provider’s existing services without requiring either that their peers change or that the provider itself be updated – up to the point they require new functionality of the service provider.

These limit cases suggest that our concerns here are not so much separated as separating. What prevents an absolute separation is the very thing that constitutes some measure of success for any distributed system: good services are used, and in being used, become a “victim” of their own success. These limits to the separation of concerns are surfaced as a third type of contract: the consumer-driven contract. Such contracts measure the success of a service, insofar as they catalogue its obligations, whilst at the same time describing when and where a variation in concern A (the provider contract) will induce a change in concern B (one or more consumer contracts).

Service Indirection

Another question I sometimes get asked is: aren’t your three contracts really only applicable in point-to-point scenarios, where consumers communicate directly with a service provider?

It’s important here to distinguish between the accountability of a service and its location. As a consumer of services, I tend to want to delegate my business to providers I trust, even if I don’t quite know where the specific person, department or office dealing with my request is located. Accountability in this instance is really shorthand for my ability to determine whether a provider is capable of satisfying my functional and quality-of-service requirements, and thereafter to demand traceability of it in respect of any requests I make. I’d be foolish to delegate my interests to some anonymous party I know nothing about, and from whom I can’t secure a guarantee of accountability, which is why I tend to draw back from an SOA-ad-absurdum that encourages me to fling messages into the “cloud,” to be satisfied by “something,” “somewhere.”

The key point here is that consumer-driven contracts require a site of responsibility or accountability. Mediated, brokered and routed messaging scenarios are perfectly amenable to consumer-driven contracts just so long as they don’t diminish service responsibility. It may be that I delegate some of my due diligence activities to a broker, which then matches my requirements against trusted providers; but even here, where I don’t know who exactly is satisfying my requests, I have a trust relationship, an expectation-obligation relationship, with at least one party – the broker – and therefore a potential site for consumer-driven contracts.

Theory into Practice

I ended my last post with the suggestion that in many cases it’s useful for a service provider to know something of its consumer-driven contract. Assuming you do want to know more about a provider’s current contractual obligations, we then need to ask: can you in fact discover what those obligations are? Can you identify a service’s consumers?

The answers to these questions will vary according to the environment in which a service provider is situated. In an enterprise environment, one in which the landscape is well known, it is often possible to identify all consumers of a service. Outside the enterprise, things may be more difficult. Services on the Web, for example, may have a largely anonymous clientele, making it near impossible to discover “existing” contractual obligations.

That’s not the end of the problem. Even if you can identify a consumer, it may still prove difficult to establish whether a relationship between that consumer and the provider is in fact currently in force. Whilst many such relationships are long-lived, particularly in the enterprise (I’m not talking about long-lived instances of a connection or transaction, merely the fact that for some period of time we can confidently say that service X is likely to collaborate or have some relation with service Y to satisfy such-and-such a business process), others are more ad hoc and less easily identified – a function of an agent crawling a service inventory, perhaps. In these circumstances, a snapshot of contractual obligations, even if some such thing could be generated, may well have some fuzzy edges.

The twin issues of the liveness and lifetimes of consumer-driven contracts and the consumer contracts from which they are derived are of renewed interest to me today. When does a consumer-driven contract begin? When does it end? When does it change?

I’ve no doubt that all three kinds of contract – provider, consumer and consumer-driven – are more or less in play in every distributed interaction, irrespective of the architectural and implementation decisions that have helped shape that interaction. But it’s clear to me now that the separation of concerns described in my original article was influenced heavily by the relatively static nature of the Web Services stack’s contract mechanism. WSDL is an upfront (partial) declaration of a provider contract. Clients activate an application protocol – engage in a conversation with a service – by invoking the operations that have been published in the WSDL (the protocol’s not inherent in the contract, only the levers by which it can be activated). By contrast, more RESTful services allow for a certain dynamism in the conversational aspects of a provider contract: representations in and of themselves advertise the levers by which a client can advance the application protocol, and they do this without reference to some pre-existing static contract map. Provider contracts in such services are “for the now,” and are exhausted in being consumed.

How do the forces at play in a RESTful interaction affect our understanding of consumer-driven contracts? If they make it more difficult to describe consumer relations outside of a specific instance of an interaction, do they not also make it correspondingly less important to know something of the consumer relation? My thinking is not settled on these issues. Sometimes I’m inclined to think of a consumer-driven contract as a resource, as a promise to provide such-and-such, to be provisioned by the provider for a certain period of time; at other times I prefer to see it as a function of per-request content negotiation. More on this another time.

Summary

In summary, Consumer-Driven Contracts describes in some detail the forces in play in any loosely coupled relationship. It does this by proposing that three types of contract exist between service providers and consumers. Real-world implementations of distributed systems exhibit all three types of contract, but the degree to which we can describe each contract, and the need to do so, varies according to the context.

Atom   RSS 2.0   Email

Events in April

April 4th, 2008  |  Published in Events by Ian Robinson

I’m going to be speaking at a couple of events towards the end of April:

Microsoft Architect Insight Conference

On the 29th April I’ll be presenting at the Microsoft Architect Insight Conference on the topic of Enterprise Web Integration Using .NET 3.5. The talk illustrates how Web-friendly integration methods helped a large company with over 60 systems solve their more serious integration and process agility issues. Traditional enterprise integration approaches having been tried and found wanting, the company adopted Web-based syndication to supply timely events to the systems implementing its key business processes.

Faced with an expensive, complex and tightly coupled database integration strategy, the integration team decided to take a consumer-driven approach to identifying the significant interactions between business functions. The team identified the minimum set of business-meaningful interactions necessary to implement a distributed business process, and then surfaced those interactions as first-class citizens of the systems estate in a Web-friendly, resource-oriented manner.

The session includes code samples that show how the solution surfaced business interactions as Atom feeds using the syndication features built into .NET 3.5.

Some of the key advantages of this approach:

  • Web-based integration approaches require minimal upfront infrastructure investment
  • Business-meaningful interactions become first-class citizens of the service estate, rather than being buried inside a database replication strategy or middleware platform
  • Interactions with well-defined business semantics drive out the minimum of functionality required to satisfy a business capability
  • Consumer expectations imported into a service provider in the form of tests or assertions comprise the contract between the provider and its consumers
Event
Microsoft Architect Insight Conference
Description
Enterprise Web Integration Using .NET 3.5.
Date
29th April
Time
12 pm - 1 pm
Location
Beaumont House
Burfield Road Old Windsor Berkshire SL4 2JP

ThoughtWorks Anthology Calgary Launch

The next day, 30th April, I’ll be on the other side of the planet, attending the ThoughtWorks Anthology launch in Calgary. Also in attendance will be Stelios Pantazopoul and ThoughtWorks’s CTO, Rebecca Parsons. We’ll talk a little about our contributions to the book, snaffle the wine, and then head off to the James Joyce for a quick “standup.”

Event
Calgary launch of the ThoughtWorks Anthology
Date
30th April
Time
5.30 pm - 7 pm
Location
McNally Robinson
120 8th Ave SW Calgary AB T2P 1B3

Add to your calendar

Atom   RSS 2.0   Email