MIT OpenCourseWare
  • OCW home
  • Course List
  • about OCW
  • Help
  • Feedback
  • Support MIT OCW

Exercise 4: Getting It Right

Due: Week 5

Handout E4

We recommend that you read the entire problem set before you begin work.

Introduction

In this exercise, you'll apply some techniques for improving the quality of software. As an example to study, you'll use your graph design and implementation from last week.

You'll use object models to capture the crucial invariants in the graph's design and implementation. You'll record the representation invariant and abstraction function, and you'll implement them as methods. You'll write runtime assertions to check preconditions, representation invariants, and other important internal invariants.

As you do this, you may well discover bugs in your code. You're also likely to discover ways that you can improve your representation, and maybe your specification. You should expect to rewrite much of your code. You shouldn't have a lot of code, so this shouldn't be a burden. And there are few ways to improve your programming skills that are more effective than reworking code.

Constructing object models takes some practice, and can seem more of a burden than a benefit until you are fluent. So the first problem of this exercise asks you to construct some tiny models of simple and familiar domains. So far, you've only seen object models of code, in which the objects in a set represent Java™ objects and the fields represent instance variables. In these more problem-oriented models, you'll have to think more abstractly, in terms of sets of objects in the real world, and relations between them. You may want to look over the material on 'data models' in the course text to get you started.

Problem 1: Object Model Warm-ups (15 points)

Construct an object model for each of these domains. In each case, draw a diagram and add as textual annotations any constraints that are not readily expressible in the diagram. You should ignore mutability concerns.

  1. A pack of cards consists of cards, each of which has a number and a suit, except for the joker. No two cards have both the same number and same suit.
  2. A propositional formula is an and-formula, or an or-formula, or a not-formula, or a literal. And-formulas and or-formulas are lists of propositional formulas. A not-formula is a propositional formula.
  3. Domestic airspace is divided into regions known as centers. Each center is divided into sectors, and has a supervisor. Each air-traffic controller is assigned to a single sector.
  4. A book has a preface, one or more chapters, and maybe an index. The index associates topic names with pages of the book. The index never refers to pages in the preface or the index itself.
  5. A degree program consists of courses. There are a number of concentrations. Each concentration has a header course, and one or more elective courses. A course may have prerequisites: a set of courses that must be taken before it. A course's prerequisites are always offered in the same degree program as the course itself. A course may not have itself as a prerequisite.

Problem 2: Graph Invariants (50 points)

Construct the following artifacts:

An abstract object model of your graph type, at the level of abstraction of the specification. That is, the objects in the model should be those visible to a client of the type.

A concrete object model of your graph type, at the level of abstraction of the implementation. That is, the objects in the model should include all those involved in the representation. Make sure you include information about sharing of objects, about mutability, and about which references may be null. 

A representation invariant for your graph. This should be a textual constraint, consistent with the concrete object model. Indicate which properties of the representation invariant are also captured by the concrete object model, and which properties of the concrete object model do not appear in the representation invariant. Cut and paste the declarations of the relevant fields of your class (and any other relevant classes that belong to the representation) to go along with the invariant.

An abstraction function for your graph. This should define how to obtain an instance of the abstract object model from an instance of the concrete object model.

An implementation of the representation invariant as a method repCheck that takes no arguments, returns void, and throws an exception if the invariant is violated. The method need not check every property of the invariant; you should make a good engineering judgment about which properties are feasible to test. You should not be concerned that executing the method will damage the performance of the graph implementation.

An implementation of the abstraction function as a toString method. The string returned should represent the abstract value exactly as described in your abstract object model and abstraction function.

A list of problems (if any) that you found in your code by thinking about these artifacts.

Problem 3: Graph Tests (30 points)

Instrument your graph code with calls to repCheck and runtime assertions for any other important invariants that you expect to hold at points in the code.

Construct a test suite for your graph. To select your test cases, consider both the specification and the implementation. Your tests should achieve complete branch coverage, and should cover every boundary case apparent from the specification. Try not to use any more test cases than you need.

Run the tests using JUnit, and report the results.

You should hand in:

A new copy of your graph code, instrumented with the new assertions, and modified in response to problems you found in your analysis.

Your test suite, commented to indicate which test cases provide coverage of which features.

A list of problems (if any) that you found in your code when you ran the tests.

A statement indicating which of your tests succeed. If you omit this, we will assume that your tests fail.

Problem 4: Modelling The T (5 points)

The Boston subway (the "T") is not just a graph whose nodes are stations and whose edges are track segments. You might have noticed that your program, being based on a generic graph, cannot easily handle some of the peculiarities of the T. If you were developing a realistic program for the MBTA, you would need to account for these. A good start would be to build an object model that captures the structure of the T and of journeys on the T, which you could then use as the basis for the design of some abstract data types.

Construct such an object model. It should express the fact that a journey involves stages, each of which is a sequence of track segments on a single line. It should also support giving directions for the Green Line that tell you which train to take at Park Street, for instance.

Q & A

This section will list clarifications and answers to common questions about the exercise. We'll try to keep it as up-to-date as possible, so this should be the first place to look (after carefully rereading the handout) when you have a problem.