Software Engineering for Students A Programming Approach
Software Engineering for Students A Programming Approach Software Engineering for Students A Programming Approach
17.8 Assertions 253 as in fly-by-wire airplanes, each version runs on a separate (but identical) processor. The voting module is small and simple, consuming minimal developer and processor time. For obvious reasons, an even number of versions is not appropriate. The main difference between the recovery block and the n-version schemes is that in the former the different versions are executed sequentially (if need be). Is n-programming forward error recovery or is it backward error recovery? The answer is that, once an error is revealed, the correct behavior is immediately available and the system can continue forwards. So it is forward error recovery. 17.8 ● Assertions Assertions are statements written into software that say what should be true of the data. Assertions have been used since the early days of programming as an aid to verifying the correctness of software. An assertion states what should always be true at a particular point in a program. Assertions are usually placed: ■ at the entry to a method – called a precondition, it states what the relationship between the parameters should be ■ at the end of a method – called a postcondition, it states what the relationship between the parameters should be ■ within a loop – called a loop invariant, it states what is always true, before and after each loop iteration, however many iterations the loop has performed. ■ at the head of a class – called a class invariant, it states what is always true before and after a call on any of the class’s public methods. The assertion states a relationship between the variables of an instance of the class. An example should help see how assertions can be used. Take the example of a class that implements a data structure called a stack. Items can be placed in the data structure by calling the public method push and removed by calling pop. Let us assume that the stack has a fixed length, described by a variable called capacity. Suppose the class uses a variable called count to record how many items are currently in the stack. Then we can make the following assertions at the level of the class. These class invariant is: assert count >= 0; assert capacity >= count; These are statements which must always be true for the entire class, before or after any use is made of the class. We can also make assertions for the individual methods. Thus for method push, we can say as a postcondition: assert newCount = oldCount + 1; For the method push, we can also state the following precondition: assert oldCount < capacity;
254 Chapter 17 ■ Software robustness SELF-TEST QUESTION 17.9 Write pre- and post-conditions for method pop. Note that truth of assertions does not guarantee that the software is working correctly. However, if the value of an assertion is false, then there certainly is a fault in the software. Note also that violation of a precondition means that there is a fault in the user of the method; a violation of a postcondition means a fault in the method itself. There are two main ways to make use of assertions. One way is to write assertions as comments in a program, to assist in manual verification. On the other hand, as indicated by the notation used above, some programming languages (including Java) allow assertions to be written as part of the language – and their correctness is checked at runtime. If an assertion is found to be false, an exception is thrown. There is something of an argument about whether assertions should be used only during development, or whether they should also be enabled when the software is put into productive use. 17.9 ● Discussion Fault tolerance in hardware has long been recognized – and accommodated. Electronic engineers have frequently incorporated redundancy, such as triple modular redundancy, within the design of circuits to provide for hardware failure. Fault tolerance in software has become more widely addressed in the design of computer systems as it has become recognized that it is almost impossible to produce correct software. Exception handling is now supported by all the mainstream software engineering languages – Ada, C++, Visual Basic, C# and Java. This means that designers can provide for failure in an organized manner, rather than in an ad hoc fashion. Particularly in safety-critical systems, either recovery blocks or n-programming is used to cope with design faults and enhance reliability. Fault tolerance does, of course, cost money. It requires extra design and programming effort, extra memory and extra processing time to check for and handle exceptions. Some applications need greater attention to fault tolerance than others, and safety-critical systems are more likely to merit the extra attention of fault tolerance. However, even software packages that have no safety requirements often need fault tolerance of some kind. For example, we now expect a word processor to perform periodic and automatic saving of the current document, so that recovery can be performed in the event of power failure or software crash. End users are increasingly demanding that the software cleans up properly after failures, rather than leave them with a mess that they cannot salvage. Thus it is likely that ever-increasing attention will be paid to improving the fault tolerance of software.
- Page 225 and 226: 202 Chapter 15 ■ Object-oriented
- Page 227 and 228: 204 Chapter 15 ■ Object-oriented
- Page 229 and 230: 206 Chapter 15 ■ Object-oriented
- Page 231 and 232: 208 Chapter 15 ■ Object-oriented
- Page 233 and 234: 210 Chapter 15 ■ Object-oriented
- Page 235 and 236: 212 Chapter 15 ■ Object-oriented
- Page 237 and 238: 214 Chapter 15 ■ Object-oriented
- Page 239 and 240: 216 Chapter 15 ■ Object-oriented
- Page 241 and 242: 218 Chapter 15 ■ Object-oriented
- Page 243 and 244: 220 Chapter 15 ■ Object-oriented
- Page 245 and 246: 222 Chapter 16 ■ Programming in t
- Page 247 and 248: 224 Chapter 16 ■ Programming in t
- Page 249 and 250: 226 Chapter 16 ■ Programming in t
- Page 251 and 252: 228 Chapter 16 ■ Programming in t
- Page 253 and 254: 230 Chapter 16 ■ Programming in t
- Page 255 and 256: 232 Chapter 16 ■ Programming in t
- Page 257 and 258: 234 Chapter 16 ■ Programming in t
- Page 259 and 260: 236 Chapter 16 ■ Programming in t
- Page 261 and 262: 238 Chapter 17 ■ Software robustn
- Page 263 and 264: 240 Chapter 17 ■ Software robustn
- Page 265 and 266: 242 Chapter 17 ■ Software robustn
- Page 267 and 268: 244 Chapter 17 ■ Software robustn
- Page 269 and 270: 246 Chapter 17 ■ Software robustn
- Page 271 and 272: 248 Chapter 17 ■ Software robustn
- Page 273 and 274: 250 Chapter 17 ■ Software robustn
- Page 275: 252 Chapter 17 ■ Software robustn
- Page 279 and 280: 256 Chapter 17 ■ Software robustn
- Page 281 and 282: 258 Chapter 17 ■ Software robustn
- Page 283 and 284: 260 Chapter 18 ■ Scripting GNU/Li
- Page 285 and 286: 262 Chapter 18 ■ Scripting In sum
- Page 288: PART D VERIFICATION
- Page 291 and 292: 268 Chapter 19 ■ Testing We begin
- Page 293 and 294: 270 Chapter 19 ■ Testing within a
- Page 295 and 296: 272 Chapter 19 ■ Testing Test num
- Page 297 and 298: 274 Chapter 19 ■ Testing if (a >=
- Page 299 and 300: 276 Chapter 19 ■ Testing 3. apply
- Page 301 and 302: 278 Chapter 19 ■ Testing made con
- Page 303 and 304: 280 Chapter 19 ■ Testing 19.3 Dev
- Page 305 and 306: 282 Chapter 19 ■ Testing 19.2 The
- Page 307 and 308: 284 Chapter 20 ■ Groups The term
- Page 309 and 310: 286 Chapter 20 ■ Groups Of course
- Page 311 and 312: 288 Chapter 20 ■ Groups • Exerc
- Page 314 and 315: CHAPTER 21 This chapter explains: 2
- Page 316 and 317: Stage Input Output 21.3 Feedback be
- Page 318 and 319: Summary The essence and the strengt
- Page 320 and 321: CHAPTER 22 This chapter: 22.1 ● I
- Page 322 and 323: 22.2 The spiral model 299 to try to
- Page 324 and 325: 22.4 ● Discussion Exercises 301 A
17.8 Assertions 253<br />
as in fly-by-wire airplanes, each version runs on a separate (but identical) processor. The<br />
voting module is small and simple, consuming minimal developer and processor time.<br />
For obvious reasons, an even number of versions is not appropriate.<br />
The main difference between the recovery block and the n-version schemes is that<br />
in the <strong>for</strong>mer the different versions are executed sequentially (if need be).<br />
Is n-programming <strong>for</strong>ward error recovery or is it backward error recovery? The<br />
answer is that, once an error is revealed, the correct behavior is immediately available<br />
and the system can continue <strong>for</strong>wards. So it is <strong>for</strong>ward error recovery.<br />
17.8 ● Assertions<br />
Assertions are statements written into software that say what should be true of the data.<br />
Assertions have been used since the early days of programming as an aid to verifying the<br />
correctness of software. An assertion states what should always be true at a particular<br />
point in a program. Assertions are usually placed:<br />
■ at the entry to a method – called a precondition, it states what the relationship<br />
between the parameters should be<br />
■ at the end of a method – called a postcondition, it states what the relationship<br />
between the parameters should be<br />
■ within a loop – called a loop invariant, it states what is always true, be<strong>for</strong>e and after<br />
each loop iteration, however many iterations the loop has per<strong>for</strong>med.<br />
■ at the head of a class – called a class invariant, it states what is always true be<strong>for</strong>e<br />
and after a call on any of the class’s public methods. The assertion states a relationship<br />
between the variables of an instance of the class.<br />
An example should help see how assertions can be used. Take the example of a class<br />
that implements a data structure called a stack. Items can be placed in the data structure<br />
by calling the public method push and removed by calling pop. Let us assume that<br />
the stack has a fixed length, described by a variable called capacity. Suppose the class<br />
uses a variable called count to record how many items are currently in the stack. Then<br />
we can make the following assertions at the level of the class. These class invariant is:<br />
assert count >= 0;<br />
assert capacity >= count;<br />
These are statements which must always be true <strong>for</strong> the entire class, be<strong>for</strong>e or after<br />
any use is made of the class. We can also make assertions <strong>for</strong> the individual methods.<br />
Thus <strong>for</strong> method push, we can say as a postcondition:<br />
assert newCount = oldCount + 1;<br />
For the method push, we can also state the following precondition:<br />
assert oldCount < capacity;