On this page:
Lab 3 Description
Game change
Understanding mutation
Version: 5.2.1

Lab 3

Lab 3 Description

The goal of this lab is to think about the design of tests in the presence of mutation. The third part studies the meaning of equality and the design of equality comparison.

Game change

The library impworld.jar aupports the design of the interactive games using imperative style (mutation). The methods onTick, onKeyEvent, OnMouseClisk(Posn p), (and all other mouse handling methods) have the return type void. Each method causes the state of the game to be modified to reflect the desired changes.

The tests for the methods with effects are more difficult. We need to make sure the data we use is set up as desired, invoke the method whose effects we want to test, then run the tests (and possibly, clean up after the test).

The starter files:

Start a new project, import the solution in the functional style, as well as all the needed images. Add to the classpath the libraries: worldcanvas.jar, worldimages.jar, impworld.jar, colors.jar, and tester.jar.

Understanding mutation

Our goal is to provide examples where mutation is necessary. Our simple scenario involves two kinds of bank accounts, a checking account and a savings account, and the account owners. We need methods that will record deposits, withdrwals, and provide information about available funds.

The starter files:

The Motivation

We start by defining the classes that represent the banking data. The file ExamplesBankingData provides this, including example of data, and the templates for the methods.

Circularity

Think of what would happen to the data definitions and the constructors if every person could have just one account, but the account would include the fields that represented the account owner, and the owner’s data would refer to the owner’s account.

The class diagram would be:

     +------------+ +-----------+

     |            | |           |

     v            | |           v

+--------------+  | |  +----------------+

| Person       |  | |  | Acct           |

+--------------+  | |  +----------------+

| String name  |  | |  | int acctNo     |

| Acct account |----+  | int balance    |

+--------------+  |    | int minBalance |

                  +----| Person owner   |

                       +----------------+

We could not make examples of data without first creating an incomplete object and only later initializing the remaining fields. In this case, the Person would have no account, then when the account was created, the information about if would be provided to the Person object.

This kind of circularity appears in many situations, and is not always as obvious as in this example. The text How to Design Classes has a discussion of this problem in depth. We mentioned it, because it is one of the examples that motivates the need for mutation.

The object has an owner, and so it cannot be replaced

In our example the person knows about the account it owns. If the account instance is replaced by a new one every time we wish to make a change, the account owner will not notice the change.

An object may have more than one owner, which makes test more complex

Our examples allow two or more people to own jointly an account. (In our example mom and dad share the savings account though both have their own checking account.) Here the tests for the effect of the method should verify that the change in the account values has been seen by all owners of the account.