Introduction
Design by Contract is a branch of coding technique or a methodology that derives from Interface-based programming. Intuitively speaking, if some day by mistake you created an object and part of its behavior complies with an interface and you instantiate that object with an interface reference to it, you are employing a technique called Design by Contract.
The creators of that technique obtained it by viewing the contracts and formal agreements that usually happen between contractors (businesses) and clients (end-users) who after signing the contract adhere to the rules to it including Scheduled delivery date, Support Project requirements, and so forth. What the creators noticed is that a contract usually governs the Know-How and How-To of a certain product to the proprietary of its supplier, and focuses exclusively on the communication between the endpoints for the support and the delivery of the product. That same technique is applied to our programming world.
So the principal idea of Design by Contract is that a class and its clients have a contract with each other: The client must guarantee certain conditions before calling a method specialized on the class; the class guarantees certain properties after the call.
Applying DbC
A misconception happens when people think of DbC as a combination of Attributes and Interfaces, as I read in an article posted on the same website. DbC is, first and foremost, a technique used in the abstraction-level or the high-level layer when designing an application or a pattern. When used properly, Interfaces (intention) and classes that implement the interfaces (Implementation) give birth to a policy that prohibits (hides) the details (specific behavior) of a class.
DbC is at the core of component development. Most COTS (Commercial-on-the-shelf) components rely heavily on separating intention from implementation, and thus provide the users of the component with public interfaces to access it.
Interfaces make a heavy use of polymorphism, allowing the call of heterogeneous objects that have similar behavior; this is a very important technique when designing complex objects.
Since multiple inheritance in .NET prohibits inheriting from multiple classes, Interfaces are welcomed. One note I want to add here is that I find it useless if you inherit from multiple interfaces if you don't have a strategy behind it. Just as a rule in a contract, the intention of one rule advocates the intention of another. So the logic behind multiple interface inheritance is to include distinct specific behaviors in a class.
Another aspect which is sometimes not related to DbC but should be noted here: Interfaces play a major role in composition (composition is used to extend responsibilities by delegating work to another appropriate object). When designed properly, the Interface in that aspect becomes DbC.
Always remember, an Interface is a special reference type: you can iterate Interfaces, return Interfaces, you can use them in conjunction with parameters, you can declare arrays of an Interface, etc...
When to use DbC
To put it clearly, DbC is widely used; it's almost used anywhere in the software engineering field. Whenever you think of Maintainability, Re-use (Interface re-use), Flexibility, Security (this needs another topic or discussion), Maximum fault-tolerance, Communication between components, and implementation hiding, there is a need for DbC.
- Maintainability: widely employed in CBSE (Component-Based Software Engineering). Since COP/CBSE relies on public interfaces while communicating with other components, all internal constructs are governed beyond public interfaces, and implementation is hidden from public scope. Whenever there is a need to change the content in a class or a method, there is no need to change the public interfaces and thus the client's code is never changed.
- Re-Use: Most of the software engineers who develop applications (often components) using DbC favor reusing Interfaces and not classes or methods; most of you might argue about that, but when you consider their strategy/technique, you might think again about mimicking their methodology.
- Flexibility = Maintainability + Reuse.
- Security: I am currently designing a methodology for the sake of utilizing DbC in security. Currently, I am in the phase of embedding security at the functionality level.
- Maximum fault-tolerance = Flexibility + Well designed (Communication between components) + Implementation hiding.
Some final thoughts
I believe that DbC lies on the edge of a strategic programming practice, just as inheritance; it provides a mechanism that if implemented thoroughly will fasten your production and clears away vague design, plus, it secures you code and limits unwanted interfaces to public use.
Once my boss told me: "Jimmy, Knowledge is for everyone", and thereafter Time became equivalent to Knowledge to me. This is the first article I publish on the internet. Please understand that not all what I say is subject to correctness. I might be mistaken in some places, so please comment on what you find wrong, so we could build upon it an appropriate knowledge base for others to accelerate from.