5.3.2. Preconditions and Postconditions
As you write methods in a class, it is a good idea to keep in mind the preconditions and the postconditions for the method and write them in the comments. A precondition is a condition that must be true for your method code to work, for example the assumption that the parameters have values and are not null. The methods could check for these preconditions, but they do not have to. The precondition is what the method expects in order to do its job properly.
A postcondition is a condition that is true after running the method. It is what the method promises to do. Postconditions describe the outcome of running the method, for example what is being returned or the changes to the instance variables. These assumptions are very useful to other programmers who want to use your class and get the correct results.
Here is an example of preconditions, postconditions, and @param in the Turtle code that we have used in the past for our drawing turtles.
* Constructor that takes the x and y position for the
* Preconditions: parameters x and y are coordinates from 0 to
* the width and height of the world.
* Postconditions: the turtle is placed in (x,y) coordinates
* @param x the x position to place the turtle
* @param y the y position to place the turtle
public Turtle(int x, int y)
xPos = x;
yPos = y;
Try to break the preconditions of the Turtle constructor below. Does the Turtle constructor behave properly if you break the preconditions that x and y are between 0 and 300. Try giving the Turtle constructor x and y values out of these ranges. What happens? Does the method give good results? Does it give any warnings? What about the t.forward() method? Does it have any preconditions that you can break?
(If the code below does not work for you, you can copy the code into this repl.it link (refresh page after forking and if it gets stuck) or download the files here to use in your own IDE.)
The Turtle constructor’s precondition is that x and y should be between 0 and the width and height of the world. If it receives values out of this range, it sets x and y to the closest legal values that it can so that the turtle appears just at the edge of the world. Similarly, the forward() method will not allow the turtle to leave the world.
Check your understanding
Let’s consider the substring method in Java. This method has a strong precondition that its arguments refer to indices within the given string.
The following code breaks the preconditions of the substring method and throws an IndexOutOfBoundsException. Can you fix the code by changing the arguments for the substring method to print out the substring “lo”? What are the preconditions for the substring method?
The method str.substring(beginIndex, endIndex) has the precondition that 0 <= beginIndex <= endIndex <= str.length.
Check your understanding
5-3-3: The following method is intended to return the substring starting at index i until the end of the string. For example, getiToEnd(“012”,1) should return “12”. Which of the following is the most appropriate precondition for the method so that it does not throw an exception?
/* missing precondition */
public String getiToEnd(String str, int i)
return str.substring(i, str.length());
- /* Precondition: i >= 0 */
- This is true but it could still throw an exception if i is a large value.
- /* Precondition: i <= str.length() */
- This is true but it could still throw an exception if i is a negative value.
- /* Precondition: 0 < i < str.length() */
- This is true but a little too restrictive.
- /* Precondition: 0 <= i < str.length() */
- Correct. i can refer to character 0 up to str.length().
5.3.3. Software Validity and Use-Case Diagrams
Preconditions and postconditions are covered on the AP CS A exam. Software validity, testing, and use-case diagrams which are discussed in this subsection are not covered on the AP CS A exam, but they are described here because they use preconditions and postconditions and are used by professional programmers.
Determining the preconditions and postconditions help us to test our code and determine the validity of our software. Software validity tests whether the software does what it is supposed to do before it is released. This is sometimes very important. For example, if the code is part of a satellite going to outerspace or is going to be used in an emergency condition, we want to test it thoroughly and make sure it works and is valid before it is put into use.
Good software testers actually try to break the code! They try all kinds of input to see what the software will do because you never know what users will try or what conditions there will be. So, always think what the preconditions of your code are and see what happens when you break them, and then see if you can protect or warn against that.
Preconditions and postconditions can also help us to design better software systems. Software designers often first draw a high-level Use-Case Diagram of a system that shows the different ways that a user might interact with a system before they build it. Here is a simple Use-Case Diagram of a restaurant system. It shows 2 actors in the system: the customer and the staff at the restaurant, and 3 use-cases in circles. A Use-case is a particular user interaction or situation in the system or software, and they often become methods in the program.
Figure 1: Use-Case Diagram of a Restaurant System
After drawing a Use-Case Diagram, designers write down the preconditions and the postconditions for each Use-Case. Often the successful post-condition for one use-case becomes the preconditions for the next use-case. For example, for the “Order Food” and “Eat Food” Use Cases:
Preconditions for “Order Food”: Customer enters restaurant. Staff is ready to take the order.
Postconditions for “Order Food”: Customer orders the food. Staff takes the order.
Preconditions for “Eat Food”: Customer has already ordered food. Staff has delivered food.
Postcondition for “Eat Food”: Customer eats the food.
Check your understanding
5-3-4: What are the preconditions and postconditions of the use-case “Pay for food”? Remember that these are often related to the other use-case conditions “order food” and “eat food”.
5.3.4. Agile Software Development
There are many different models for software development. The waterfall model, developed in the 1970s, is a step by step model where each phase is finished before the next phase begins. This model has recently been criticized because it is not very adaptable. The more recent Agile development model involves iterative, incremental development where teams works in short 2-3 week sprints to completely develop, test, and release a component of the project to the customer for feedback. It is very adaptable as project requirements change because of early testing, immediate customer feedback and collaboration.
Figure 2: Waterfall vs Agile Models
One very popular type of agile development is called Scrum. The following short video describes software development with Scrum.
Try the Wake Up In the Morning Game in groups to practice the iterative and incremental agile development process.