Practical .NET
It’s Time to Reconsider Using Contracts
Coding by Contract was once the future of programming. It isn’t as popular now as it was even five years ago, at least in the .NET Framework community. But that doesn’t mean you can’t find the related tools useful.
In this column, I want to rehabilitate code contracts. Code Contracts are a way for you to declaratively apply constraints to your code. A "constraint" is a condition, applied to a class, that must be true for the class to be used successfully. "Declarative" means that you don’t have to write a bunch of procedural code to apply your constraint. You have to like both of those things.
Contracts, at least in theory, are a good thing: Not only do they give you a way to control how a class works, they also can tell developers -- at compile time -- that they’re not using your class correctly. Contracts can also provide advice on preventing runtime errors that you might not have thought of (again, at compile time) and ensure a more consistent UX.
Given all that, you have to ask why you’re not using contracts right now. To put it another way, why do contracts need "rehabilitation"? There’s a story there . . .
The Case Against Contracts
In fact, there was a time that "Coding by Contract" (CbC) was the "future of programming" and CbC was a hot style of programming -- until it wasn’t. There are a couple of reasons for that.
One reason was disillusionment with CbC. To begin with, developers would write a bunch of constraints that specified how a class was to behave. Developers then discovered that their constraints were overly strict and had to back some of them out. About the same time, developers also discovered that, with the tools that the .NET Framework made available, they couldn’t even declare some constraints they wanted to. These two discoveries left a feeling that contracts weren’t doing everything they should.
At least one developer, experienced with the Eiffel language where CbC is the norm, summed up these deficiencies. In defense of the current state of code contracts in the .NET Framework, that blog post is from seven years ago and much has changed since then.
The second reason CbC stopped being hot was the rise of automated testing and test-driven development. CbC provides a way to specify, as part of creating a class, that your code will do the right thing. Automated testing does something very similar: It provides a way of ensuring, after you write a class, that your code has doe the right thing. Because automated testing lets you write whatever procedural test you want, it provides the flexibility that developers miss in CbC while achieving many of the same goals.
The Case for Contracts
But we needn’t, as the cliché goes, throw out the baby with the bathwater. If there are things that CbC won’t do the answer is, just don’t do them -- you can have automated testing take care of those issues that CbC doesn’t address. In addition, CbC and automated testing can work together: You can declare a restriction in your contract and use a test to prove that it’s working … or omit the test because you have a contract in place. With the right toolset, Visual Studio won’t compile your code if you’re violating your contracts. With or without tests, you won’t have to write the procedural (and, potentially, buggy) code that implements the constraint in your class.
Besides, regarding CbC as being just about control misses the point. When you declare a constraint in CbC, Visual Studio and the .NET Framework will automatically convert that constraint into validation code in your application. As a result, any developer who uses your class with a contract "inherits" a whole bunch of validation code that the developer no longer has to implement. This is obviously a good thing.
From a user experience point of view, contracts also help to ensure consistency: Code contracts ensure that the same messages are provided for the same errors across the UIs that use your class.
Finally, using contracts lets you discover more problems with your code at compile time rather than run-time (or even "test-time"). This process, called static checking, looks for conditions in your code that will violate constraints in your contracts and flags them as part of compiling your code. The latest version of the toolset will even recommend additional declarative validation tests that you can insert into your code to catch more errors at run-time.
CbC may not be the "future of programming" any more, but that doesn’t mean that the tools that are part of the Framework aren’t worth applying. I’ll demonstrate how you can leverage those tools to create applications in a future column.
About the Author
Peter Vogel is a system architect and principal in PH&V Information Services. PH&V provides full-stack consulting from UX design through object modeling to database design. Peter tweets about his VSM columns with the hashtag #vogelarticles. His blog posts on user experience design can be found at http://blog.learningtree.com/tag/ui/.