« Two sites that need RSS feeds | Main | Werner sums it up »

Versioning: some strategies and tactics

'Any software needs to have a coherent versioning strategy baked into the initial version. Version 2.0 (or 1.1, or 1.0.1, or whatever) is too late. By then, the horses have already left the barn. When calculating the TCO and ROI for a software project that does not have a coherent plan for enabling loosely coupled versioning that can enable forwards- and/or backwards-compatible changes, the initial deployment cost (at least) should be used as a measure for the inevitable version dot next and added to the overall support cost. -Chris Ferris'

I agree with Chris and so do these folks. I don't read Chris as saying that using numbers to represent versions are misguided but that version numbers alone are only symbols and are thus insufficient - there must be a defined policy in place from the beginning.

Something else came to mind while reading Chris' observations on the versioning discussion between Norm Walsh and David Orchard. There's plenty of architectural thinking around versioning in the fields of web services, service orientation and protocol design, but there's much less advice available to practitioners on versioning. So, here are some thoughts for dealing with versioning...

  1. Treat versioning as an architectural necessity. Retrofitting a versioning policy onto an existing system is hard work, especially if that system's stakeholders are independent and possibly conflicting actors. Also, it's unlikely all stakeholders will have an incentive to upgrade down the line, even within the confines of an single enterprise. To avoid friction and ensure the system can evolve in a controlled manner it's important to be clear that the architecture need cater for change. Therefore be explicit in the architecture about what the versioning policy will be.
  2. State a versioning policy as a requirement. Define the ability to handle multiple versions with respect to that policy as a requirement. Work versioning stories into your use cases. This encourages everyone involved to start thinking in operational and cost terms about versioning and ideally tees up developers to implement with versioning in mind.
  3. Treat versioning as an engineering risk - early on. From a delivery and initial implementation standpoint, dealing with a versioning policy can be considered an exercise in risk that needs to be actively managed. That's slightly different from the architectural and stakeholder view where not having a versioning policy is itself a risk. A versioning policy will imposes a complexity burden on developers that affect scheduling and initial delivery costs (this is the investment or 'opportunity cost' versus the overall lifetime cost incurred by not doing so). So, if versioning is an architectural necessity it's also a engineering risk early on - understanding this tension will be important. Aside from that it's natural for fear of breakage to set in when it comes to running a system of services; the longer a service runs the more likely it is to be critically important to one or more people. In that case change can become more difficult and risky than it needs to be - worst case is the service or its data format will become effectively frozen. Later as the service evolves the initial risk undertaken will reap it reward as the developers will be in a position to undertake changes.
  4. Get feedback early - implement with multiple versions. Customers and users will need reassurance that the versioning will work from the outset. Here's an approach for delivering services that can act as expected with respect to a versioning policy - begin with two versions in play. Not only will you have demonstrated the system can handle one or more versions, you'll have empirical evidence that the versioning policy itself is sound. As well as helping with such things as calculating ROI and managing risk, it will add confidence that the system is in fact, evolvable.
  5. Software processes won't be enough - tailor them. If you use agile or open source approaches to ship code this may all just sound like hot air - 'release early, release often' with more words. To some extent in that is true and it we might think it true in terms of delivering components. Yet even for components, versioning has proven to be a real headache - consider the various approaches to the issue in COM, J2EE and. NET1. For services and systems that expose web based APIs the stakes are raised yet again - interfaces and data formats become critical points of breakage2. Getting stories and use cases to arrive with versioning requirements (which are non-functional) is important. You can get into situations in purely agile or TDD approaches where you will end up breaking users of a service by altering data formats or protocol interfaces. Indeed you may be breaking users you didn't even know you had. On the other hand approaches such as the RUP or agressive change control management run the risk of deferring feedback on versioning problems late in the development cycle or after the system has been delivered3.

[1] In Internet protocol design the default approach has been to reduce the risk of breakage by having highly constrained but highly generic interfaces.

[2] Perhaps the best articulation of this issue for those coming at it from the developer or OO side is Martin Fowler's essay, Public v Published Interfaces[PDF]

[3] Steve Loughran has argued that for Web Services, the development cycle should be extended to cater for post deployment integration issues and consequent feedback on the basis that you don't really integrate a Web Services system until you go live. This is called 'Continuous Deployment'. See chapter 2 of the excellent paper 'Making Web Services that Work'[PDF]

January 3, 2005 01:16 PM


Post a comment

(you may use HTML tags for style)

Remember Me?

Trackback Pings

TrackBack URL for this entry: