Design by contract
RobertLechte (Talk | contribs) |
RobertLechte (Talk | contribs) |
||
Line 37: | Line 37: | ||
What seemed intuitively correct (because a Security door IS a Door) was wrong. Design by contract helps us avoid falling into such traps, much as real contracts help commerce run smoothly. | What seemed intuitively correct (because a Security door IS a Door) was wrong. Design by contract helps us avoid falling into such traps, much as real contracts help commerce run smoothly. | ||
− | When contemplating a subclass, we must ask ourselves not whether the subclass '''"IS"''' the superclass, but whether | + | When contemplating a subclass, we must ask ourselves not whether the subclass '''"IS"''' the superclass, but whether it '''"SATISFIES THE CONTRACTS OF"''' the superclass. |
Revision as of 00:21, 25 September 2008
The "Contract" part of Design by Contract is a metaphor relating real-world contracts. For instance, a Acme Construction may sign a business contract to build a skyscraper, for a price of $100 million. Legally, the contract means that Acme Construction must build the skyscraper to at least the standard agreed, and may demand $100 million dollars (but no more) as payment.
If we consider this business arrangement from the perspective of Acme Construction, we can regard the contract as a set of preconditions and postconditions:
Preconditions: The building must be built on time and to the required standard.
Postconditions: Acme Construction must receive $100 million dollars.
Acme Construction is free to build the building to a higher standard (if they want to) but not a lower standard. Also, they might choose to accept less than $100 million dollars as payment (for some reason) but they cannot suddenly demand more.
Similarly, Design by Contract specifies preconditions and postconditions for each method. If that method is called, it "promises" or "guarantees" to satisfy a number of postconditions, but only provided the accompanying preconditions are met.
Let us suppose we are writing a class called Door to run automatic doors. This class defines a method called open(). Its pre/postconditions might be:
Preconditions: It is within the opening hours of the building. The alarm system is off.
Postconditions: The door is opened.
Suppose we then wish to implement a security-enabled door as a subclass of Door. The open() method for SecurityDoor would have the following new conditions:
Preconditions: The user has swiped a valid card. It is within the opening hours of the building. The alarm system is off.
Postconditions: The door is opened for ten seconds only.
This is a VIOLATION of design by contract. The subclassed method now demands more, and will only guarantee less. This violates the core principle of design by contract:
REQUIRE NO MORE, PROMISE NO LESS
This means that the SecurityDoor subclass was a bad idea. If we began using SecurityDoor objects as Door objects, we would soon violate the contract. If code was written to open all doors in case of fire, for example, the code for this would not work. Security doors would unexpectedly close after ten seconds, possibly leaving firemen trapped inside!
What seemed intuitively correct (because a Security door IS a Door) was wrong. Design by contract helps us avoid falling into such traps, much as real contracts help commerce run smoothly.
When contemplating a subclass, we must ask ourselves not whether the subclass "IS" the superclass, but whether it "SATISFIES THE CONTRACTS OF" the superclass.