[3]
DejaVU Online:
Principles of Object-Oriented Software Development
(©)
| client | supplier | |
| pre-condition | obligation | benefit |
| post-condition | benefit | obligation |
For dynamically checking the invariance condition, a test should be executed when evaluating the constructor and before and after each method invocation. While a method is being executed, the invariant need not necessarily hold, but it is the responsibility of a method to restore the invariant when it is disrupted. In case object methods are recursively applied, the invariant must be restored when returning to the original caller.
An alternative approach to incorporating assertions
in a class description is presented in
class account { account
public:
account();
// assert( invariant() );
virtual float balance() { return _balance; }
void deposit(float x); to deposit money
// require( );
// promise( balance() old_balance x && invariant() );
void withdraw(float x); to withdraw money
// require( x balance() );
// promise( balance() old_balance x && invariant() );
bool invariant() { return balance() 0; }
protected:
float _balance;
};
A pre-condition limits the cases that a supplier must handle!
class account { account
public:
account() { _balance = 0; assert(invariant()); }
virtual float balance() { return _balance; }
void deposit(float x) {
require( x >= 0 ); check precondition
hold(); to save the old state
_balance += x;
promise( balance() == old_balance + x );
promise( invariant() );
}
void withdraw(float x) {
require( x <= _balance ); check precondition
hold(); to save the old state
_balance -= x;
promise( balance() == old_balance - x );
promise( invariant() );
}
virtual bool invariant() { return balance() >= 0; }
protected:
float _balance;
float old_balance; additional variable
virtual void hold() { old_balance = _balance; }
};
To establish that the contract of a derived class refines the contract of the base class it suffices to verify that the following rules are satisfied. See slide 3-inheritance.
class C : public P {
virtual void m();
}
weaken pre-condition
strengthen post-condition
class credit_account : public account { credit_account
public:
credit_account(float x) { _maxcredit = x; _credit = 0; }
float balance() { return _balance + _credit; }
float credit(float x) {
require( x + _credit <= _maxcredit );
hold();
_credit += x;
promise( _credit = old_credit + x );
promise( _balance = old_balance);
promise( invariant() );
}
void reduce(float x) {
require( 0 <= x && x <= _credit );
hold();
_credit -= x;
promise( _credit = old_credit - x );
promise( _balance = old_balance );
promise( invariant() );
}
bool invariant() {
return _credit <= _maxcredit && account::invariant();
}
protected:
float _maxcredit, _credit;
float old_credit;
void hold() { old_credit = _credit; account::hold(); }
};
|
Hush Online Technology
hush@cs.vu.nl
12/29/99 |
|
|