Tuesday, May 22, 2007

Contracts Are The Thing

Bookmark and Share

For as long as I can remember, I've been obsessed with the importance of contracts - deliberate definition/specification of component interface boundaries. In fact, I take a fair share of grief for climbing atop my soapbox on this topic. I suppose that's the price to pay for championing the cause.

The Risk

I was recently skimming through Software Systems Architecture: Working With Stakeholders Using Viewpoints and Perspectives and came across the author’s assertion that that the most important consideration in the Functional Viewpoint (logical model) is poor interface definitions:

"Many architects define their elements, responsibilities, and interelement relationships well, yet totally neglect their interface definitions. Defining interelement interfaces clearly can often be something of a chore. However, it is on of the most important tasks you can perform for the system. Without good interface definitions, major misunderstandings will occur between subsystem development teams, leading to a range of problems from obviously incorrect behavior to subtle, occasional system unreliability."

What’s a Contract?

Bertand Meyer, the designer of the Eiffel programming language, was one of the early proponents of the importance of contracts. In “A Conversation with Bertrand Meyer, Part II - Design by Contract” (http://www.artima.com/intv/contracts.html), he puts it this way, "The main purpose of contracts is to help us build better software by organizing the communication between software elements through specifying, as precisely as possible, the mutual obligations and benefits that are involved in those communications."

Taking it somewhat deeper, an effective contract specification provides an unambiguous description of the interface syntax and semantics - what it looks like and how it behaves. The contract defines the operations offered by the interface, the inputs, the outputs, the effects, and the nature or style of communication (web services, messaging, rpc, etc).

Contracts should exhibit well-known design quality attributes such as separation of concerns, high-cohesion, loose-coupling, granularity and degree of element interactions and others. We’ll come back to those in detail another day.

For today, let’s just emphasize one: the separation of concerns which engenders the ability to organize the development effort around the architecture. Effective contract definition allows individuals or teams to be assigned responsibility for delivery of specific subsystems or components, understanding how that functionality is integrated to the overall system. In other words, contracts help us to divide and conquer.

Who’s on the Hook?

It is squarely the responsibility of the Architect to lead the definition of contracts, and as mentioned above, it’s a common execution weakness. It’s essential that the Architect have ultimate responsibility and accountability for this aspect of the architecture. But the Architect is not a solo act and relies on the engagement of many team members or even multiple teams to achieve results. It’s important for the team members to understand not only “what”, but “why”. In other words, the rationale is also important. As such, successful execution of contract definition will typically require a command of the technical solution, awareness of good design attributes, and ability to orchestrate communication among interested parties - and facilitate negotiation when necessary.

As an aside, you can see a couple of important characteristics of an effective Architect in this description. In particular, a successful Architect is a strong leader and a good communicator. It is not enough to make great decisions and define great contracts. The Architect is not successful unless the contracts are well-understood and agreed to by the relevant stakeholders.

Turning back to “Software Systems Architecture”, I’ll close with the following checklist to help guide our effort and make sure we deliver on this important responsibility:

• Define your interfaces clearly and as early as possible
• Review them frequently to ensure that they are clearly understood
• Do not consider element definition complete until interfaces have been designed
• Make sure that interface definitions include the operations, their semantics, and the examples where possible.

1Rozanski, Nick; Woods, Eoin. Software Systems Architecture. Upper Saddle River, NJ.: Addison Wesley, 2005

No comments: