Download presentation
Presentation is loading. Please wait.
Published byGeorgiana Poole Modified over 9 years ago
1
OOSCCh11r1:DbC RJL 010928 Slide #1 OOSC: Ch11 vs. Predecessors [Meyer:] Equipped with the basic concepts of class, object and genericity, you can by now write software modules that implement possibly parameterized types of data structures. Congratulations. This is a significant step in the quest for better software architectures. [But] remember the role played by semantic properties, as expressed by the axioms and preconditions. They are essential to capture the true nature of the type’s instances.
2
OOSCCh11r1:DbC RJL 010928 Slide #2 OOSC Ch. 11 vs. Ch. 12 (a) Chapter 11: Design by Contract views the relationship between a class and its clients as a formal agreement, expressing each party’s rights and obligations. A key problem of software engineering is how to deal with run-time errors — with contract violations. This leads to the subject of exception handling, covered in the next chapter (12). Some important extensions to the basic ideas of Design by Contract will have to wait until the presentation of inheritance, polymorphism and dynamic binding, enabling us to go from contracts to subcontracting.
3
OOSCCh11r1:DbC RJL 010928 Slide #3 OOSC Ch. 11 vs. Ch. 12 (b) The distribution of roles between chapters 11 and 12 roughly reflects the distinction between the two components of reliability: –Correctness was defined as the software’s ability to perform according to its specification, and –Robustness was defined as its ability to react to cases not included in the specification. Assertions (this chapter) generally cover correctness, while exceptions (next chapter) generally cover robustness.
4
OOSCCh11r1:DbC RJL 010928 Slide #4 11.1: Basic Reliability Mechanisms (a) In studying classes, we have — temporarily — lost sight of this semantic aspect of the ADT concept. We will need to bring it back into the method if we want our software to be not just flexible and reusable, but also correct and robust. The effort to limit inter-module communication to the strict minimum resulted in the prohibition of such common reliability risks as global variables, and in the definition of restricted communication mechanisms, the client and inheritance relations.
5
OOSCCh11r1:DbC RJL 010928 Slide #5 11.1: Basic Reliability Mechanisms (b) Understandability : Constant emphasis on making our software elegant and readable. Automatic memory management (specifically, garbage collection) is a crucial reliability- enhancing component of any O-O environment [in Java and Eiffel, not C++]. Static typing: Without statically enforced type rules, we would be at the mercy of run-time typing errors. From these we can now take a closer look at what it will take for a software system to be correct and robust.
6
OOSCCh11r1:DbC RJL 010928 Slide #6 What it means for a software element to be correct: To consider this question meaningful, you need not only the program but also a precise description of what it is supposed to do — a specification. Correctness property: Correctness is a relative notion: Software elements are correct when they are consistent with their specifications. We express such specifications through assertions. Note that OOSC’s assertions are more than C’s “assert(p)” macro call (enabled by #include ): [C’s assert(p) tests whether a certain condition p holds at a point in the software’s execution. If p is true, assert does nothing; if p is false, it calls exit() to halt the program.]
7
OOSCCh11r1:DbC RJL 010928 Slide #7 Correctness formula {P} A {Q}: The meani ng of {P} A {Q}: “Any execution of A, starting in a state where P holds, will terminate in a state where Q holds.” P and Q are properties of the various entities involved. A denotes an operation; P is the pre-condition that A may assume; Q is the post-condition that A must satisfy. Correctness formulae (also called Hoare triples) are a mathematical notation, not a programming construct, that helps to express properties of software elements. Example: {x >= 9} x := x + 5 {x >= 13} (This valid formula is not the strongest possible one. )
8
OOSCCh11r1:DbC RJL 010928 Slide #8 The Danger of Strong Pre-conditions: The strongest possible precondition is: Sinecure 1: {False} A {Q} {P} = {False} can never be satisfied => A has no responsibility whatsoever. Q is a don’t-care post-condition. (Meyer: If you ever see such an ad, don’t bother reading post-condition Q; take the job right away :-) An A which satisfies weaker pre-conditions will handle a wider range of initial conditions (and thus impose fewer constraints on its client).
9
OOSCCh11r1:DbC RJL 010928 Slide #9 The Danger of Weak Post-conditions: The weakest possible post- condition is: Sinecure 2:{P } A {True} Q = True is always satisfied (will never be False). A’s behavior is arbitrary (as long as it terminates). P = ? is a don’t-care pre-condition. (Why does Meyer say that this is only the second- best job in the world?) A nontrivial A must satisfy stronger post- conditions (to specify all the services required by its clients).
10
OOSCCh11r1:DbC RJL 010928 Slide #10 Strong vs. Weak Terminology (1) The relative notion of “stronger” vs. “weaker” formulas is formally defined in terms of logical implication: P1 is said to be stronger than P2, and P2 weaker than P1, iff P1 implies P2 (P2 is true everywhere that P1 is true) and they are not equal (P2 is also true for at least one system ‘state’* where P1 is false). Therefore, we can legitimately speak of True as the U, and False as the U, of all possible assertions, or predicates, about object values. _______ * ‘State’ means the values of all relevant data items and objects.
11
OOSCCh11r1:DbC RJL 010928 Slide #11 Strong vs. Weak Terminology (2) We can regard a proposition P as ‘accepting’ just those states* where it evaluates to true, and rejecting those where it is false. Since every proposition implies True, True (weakly) rejects no state. False implies every proposition, so False (strongly) rejects every state. Therefore we can regard P’s relative strength as a measure of its ‘selectivity’ or discriminating power: –True is totally accepting (weakest of the P’s). –False is totally rejecting (strongest of the P’s). __________________ * ‘State’ means values of all relevant data items and objects.
12
OOSCCh11r1:DbC RJL 010928 Slide #12 Specification as Documentation Once we have defined the correctness of a software element as the consistency of its implementation with its specification, we should include the specification, as well as the implementation, in the software itself. This a novel idea: –we are accustomed to programs as defining the operations that we command our HW/SW machines to execute for us (the how); –It is less common to treat the description of the software’s purposes (the what) as being part of the software itself.
13
OOSCCh11r1:DbC RJL 010928 Slide #13 11.4: Assertion Style Syntactically, pre- and post-conditions are simply boolean expressions, with a few extensions. (1) The ‘old’’ qualifier introduced later in OSC Ch. 11, is used to deal with temporal order. (2) The semicolon is used to represent conjunctive and: n > 0 ; x /= Void (Eiffel syntax) (n>0) && (x !=Void) (‘C’ syntax) Meyer (Eiffel) also names each clause, for readability and ease of reference. For example: Positive: n > 0 Not_void: x /= Void (The semicolon is optional at the end of a line.)
14
OOSCCh11r1:DbC RJL 010928 Slide #14 11.5: Stack Example (1) Class methods implement an abstract specification of a useful task. The features of generic class Stack[G] are: –count, empty, full, put, remove, item; The specification of each feature includes –require ; –ensure ; –invariant ; –implementation; –[side effects if pre-conditions not met? - RJL].
15
OOSCCh11r1:DbC RJL 010928 Slide #15 11.5: Stack Example (2) Class STACK[G] feature -- access / readout count: INTEGER; -- Number of stack elements item: G is -- Top element (parametric type G) require not empty do … end feature-- status report empty: BOOLEAN is--Is stack empty? do … end full: BOOLEAN is-- Is stack full? do … end -- to be continued
16
OOSCCh11r1:DbC RJL 010928 Slide #16 11.5: Stack Example (3) -- Class STACK[G] declaration (continued) feature -- Element change put(x:G) is-- add x on top require - pre-condition not full do … ensure-- post-condition not empty; item = x; count = old count + 1 end remove is-- Remove top element require not empty do … ensure not full; count = old count - 1 end
17
OOSCCh11r1:DbC RJL 010928 Slide #17 11.6: Contracts for SW Reliability By associating clauses ‘require ’ and ‘ensure ’ with a routine A, the class tells its clients (in Eiffel): “If you promise to call r with satisfied, then in return, I promise to deliver a final state in which is satisfied.” The supplier of A does not have to check that the pre-conditions are valid (except to debug the clients’ code - RJL).
18
OOSCCh11r1:DbC RJL 010928 Slide #18 Sample Contract for Stack::put() put(x) OBLIGATIONS BENEFITS Client(Satisfy pre-condition:) (From post- condition:) (Caller)Only call put (x) on Get stack updated: a non-full stack. not empty; x on top (item yields x); count increased by 1. Supplier (Satisfy post-condition:) (From precondition:) (Stack::)Update stack represen-Simpler processing, tation to have x on top thanks to the (item yields x); //andassumption that stack count increased by 1; //andis not full. not empty.
19
OOSCCh11r1:DbC RJL 010928 Slide #19 Non-Redundancy Principle “Under no circumstances shall the body of a routine ever test for the routine precondition.” (Exception: debugging - see next slide - RJL.) “To obtain reliable systems we must go from the microscopic view to a macroscopic view encompassing the entire architecture.” “If we take this global view, simplicity becomes a crucial criterion.”
20
OOSCCh11r1:DbC RJL 010928 Slide #20 Redundant Tests for Debugging Meyer’s View: You can insert extra checks, but if you choose to enable them you will rely on the development environment to carry them out for you, and then remove them once the software has been debugged. (RJL: assert’s exit-on-fail becomes more palatable if conditional on #ifndef NDEBUG)…#endif
21
OOSCCh11r1:DbC RJL 010928 Slide #21 Reliability - is about Interactions: “For any system of any significant size, the individual quality of the various elements involved is not enough;” “What will count most is the guarantee that for every interaction between two elements there is an explicit roster of mutual obligations and benefits — the contract.”
22
OOSCCh11r1:DbC RJL 010928 Slide #22 The Process “Identify the consistency conditions that are necessary to the proper functioning of each client-supplier cooperation (each contract); Specify, for each one of these conditions, whose responsibility it is to enforce it: the client’s, or the supplier’s. The answer may vary, and is partly a matter of design style. But once you have made the decision … stick to it:”
23
OOSCCh11r1:DbC RJL 010928 Slide #23 Assertions - Not for User Input A pre-condition will not take care of correcting user input: –You can’t enforce contracts on users Example: A routine read_positive_integer that expects the interactive user to enter a positive number: –It is wishful thinking to include a pre-condition of the form ‘require (input > 0)’. –Include a post-condition instead: insure … //user re-entry until non-zero // implemented as a method call?
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.