CSC/ECE 517 Fall 2009/wiki 3 1 SJ: Difference between revisions
No edit summary |
|||
Line 7: | Line 7: | ||
===Assert contract=== | ===Assert contract=== | ||
The most basic contract is the assert. An assert inserts a checkable expression into the code, and that expression must evaluate to true: | The most basic contract is the assert. An assert inserts a checkable expression into the code, and that expression must evaluate to true: | ||
<pre> | |||
assert(expression); | assert(expression); | ||
</pre> | |||
an assert in function bodies works by throwing an AssertError, which can be caught and handled. Catching the contract violation is useful when the code must deal with errant uses by other code, when it must be failure proof, and as a useful tool for debugging. | an assert in function bodies works by throwing an AssertError, which can be caught and handled. Catching the contract violation is useful when the code must deal with errant uses by other code, when it must be failure proof, and as a useful tool for debugging. | ||
===Pre and Post contract === | ===Pre and Post contract === | ||
The pre contracts specify the preconditions before a statement is executed. The most typical use of this would be in validating the parameters to a function. The post contracts validate the result of the statement. The most typical use of this would be in validating the return value of a function and of any side effects it has. The syntax is: | The pre contracts specify the preconditions before a statement is executed. The most typical use of this would be in validating the parameters to a function. The post contracts validate the result of the statement. The most typical use of this would be in validating the return value of a function and of any side effects it has. The syntax is: | ||
<pre> | |||
long square_root(long x) | |||
in | in | ||
{ | { | ||
Line 25: | Line 28: | ||
return cast(long)std.math.sqrt(cast(real)x); | return cast(long)std.math.sqrt(cast(real)x); | ||
} | } | ||
</pre> | |||
===In, Out and Inheritance === | ===In, Out and Inheritance === | ||
If a function in a derived class overrides a function in its super class, then only one of the in contracts of the function and its base functions must be satisfied. Overriding functions then becomes a process of loosening the in contracts. | If a function in a derived class overrides a function in its super class, then only one of the in contracts of the function and its base functions must be satisfied. Overriding functions then becomes a process of loosening the in contracts. |
Revision as of 22:17, 18 November 2009
Advantages and Disadvantages of Programming by Contract
Introduction of Contract Programming
Contracts are a breakthrough technique to reduce the programming effort for large projects. Contracts are the concept of preconditions, postconditions, errors, and invariants. These specifications of "contract" define the interface of different element of software includes method, class, module...
Assert contract
The most basic contract is the assert. An assert inserts a checkable expression into the code, and that expression must evaluate to true:
assert(expression);
an assert in function bodies works by throwing an AssertError, which can be caught and handled. Catching the contract violation is useful when the code must deal with errant uses by other code, when it must be failure proof, and as a useful tool for debugging.
Pre and Post contract
The pre contracts specify the preconditions before a statement is executed. The most typical use of this would be in validating the parameters to a function. The post contracts validate the result of the statement. The most typical use of this would be in validating the return value of a function and of any side effects it has. The syntax is:
long square_root(long x) in { assert(x >= 0); } out (result) { assert((result * result) <= x && (result+1) * (result+1) >= x); } body { return cast(long)std.math.sqrt(cast(real)x); }
In, Out and Inheritance
If a function in a derived class overrides a function in its super class, then only one of the in contracts of the function and its base functions must be satisfied. Overriding functions then becomes a process of loosening the in contracts.
Class Invariants
Class invariants are used to specify characteristics of a class that always must be true (except while executing a member function). They are described in Classes.
for detail information of contract, please refers to the helpful reading list in [2].
The advantages of Contract Programming
- A better understanding of the object-oriented method and, more generally, of software construction.
- A systematic approach to building bug-free object-oriented systems.
- An effective framework for debugging, testing and, more generally, quality assurance.
- A method for documenting software components.
- Better understanding and control of the inheritance mechanism.
- A technique for dealing with abnormal cases, leading to a safe and effective language construct for exception handling.
Example of If statement
public class Operator { string operation; public int Execute(int x, int y) { switch(operation) { case "Add": return x + y; case "Subtract": return x - y; case "Multiply": return x * y; case "Divide": return x / y; default: throw new InvalidOperationException("Unsupported operation"); } } }
In such example of conditional statement on operator, we see that: if we want to reuse function "add" operator in the other code segment, we have to reuse whole Class operator with the value "Add". And if we want to add a new operation "Power", we need to code in the implementation of Class Operator.
Idea of Polymorphism
Facing the problem of the conditional statement, people[2] come up with refactoring method called 'Polymorphism'. The idea of Polymorphism is to replace the highly functional relationship with the subclass override procedure under abstract class. So subclass is created to encapsulate each function in the conditional statement and the conditional relation is replaced by override a common abstract class. The advantage of such idea is to separate the functionality.
Definition of Polymorphism
According to [1], Subtype polymorphism, almost universally called just polymorphism in the context of object-oriented programming, is the ability of one type, A, to appear as and be used like another type, B.
The primary usage of polymorphism in industry (object-oriented programming theory) is the ability of objects belonging to different types to respond to method, field, or property calls of the same name, each one according to an appropriate type-specific behavior. The programmer (and the program) does not have to know the exact type of the object in advance, and so the exact behavior is determined at run time.
Example of Refactoring Conditional Statement with Polymorphism
- Before refactoring
public class Operator { string operation; public int Execute(int x, int y) { switch(operation) { case "Add": return x + y; case "Subtract": return x - y; case "Multiply": return x * y; case "Divide": return x / y; default: throw new InvalidOperationException("Unsupported operation"); } } }
- After refactoring
public abstract class Operator { public abstract int Execute(int x, int y) } public class Add : Operator { public override int Execute(int x, int y) { return x + y; } } public class Subtract : Operator { public override int Execute(int x, int y) { return x - y; } } public class Multiply: Operator { public override int Execute(int x, int y) { return x * y; } } public class Divide: Operator { public override int Execute(int x, int y) { return x / y; } }
References
[1] wiki page of "Design by Contract", http://en.wikipedia.org/wiki/Design_by_contract
[2] reading list of contract, http://www.eecs.northwestern.edu/~robby/contract-reading-list/ [3] Refactoring conditional statement, http://sourcemaking.com/refactoring/replace-conditional-with-polymorphism
[4] Object Orientation Design, http://en.wikipedia.org/wiki/Object-oriented_design