Documentation Project Solutions
The Assignment
What you will actually turn in is a set of documentation for this
software. The documentation that you provide comes in two parts.
The first part is documentation for the code itself. In documenting the
code, you should follow the conventions of the Design Project:
- For each class, you should provide documetation indicating what role
instances of the class are supposed to play and how they are intended to
be used. You should describe the state of instances at the time that they
are created as well as how they are expected to evolve over time.
- For each field, you should describe its purpose. You should also
include any relevant information about its initial state as well as
information about how it changes/is changed.
- For each method or constructor, you should specify the argument and
return types as well as the relationship between them. You should also
list what the method does and, if it interacts with the object's fields
or other methods, detail these interactions.
- For each line of code, you should include information as to how it
works, what it effects, why it exists, etc.
It should be possible to read your documentation and understand what the
code is doing -- and why -- almost without reading the code itself.
You may wish to edit the code files that we have provided directly,
i.e., to write your documentation as comments in the file.
The Files
The documented code is contained in files mirroring the
originals:
These use javadoc-compatible comments which can be used to
automatically generate online
documentation.
Overview
In additon to the documentation of the code, you should write an
overview/design document of 1-3 (typewritten) pages that describes how the
code works. This need not address the specific implementations of particular
methods, but instead should give a higher-level description of how the
various pieces of code interact. This document should, for example, include
sufficient information that it would be possible to figure out which piece(s)
of code to look at/modify if we wanted to add unary minus (negative numbers),
exponentiation, or some other functionality. (You should not explicitly
address these questions; this is just to give you a sense of the purpose of
this document.)
In writing up this documentation, you should answer the following
questions (among others):
- What are the different types of objects in this system?
- What components comprise these objects?
- What actions can each of these objects take?
- What goes inside, and what interactions occur between, these
objects?
- Which of these objects are autonomous, i.e., self-animating?
- What are the paths taken by these (and other) threads of
control?
There are five major types of objects in this system: Calculator,
CalcTextGUI, CalculatorState, ButtonObj, and ButtonHandler.
- Calculator. This
is the same Calculator interface from the previous lab. It
defines useful constants, such as those identifying the different
buttons, as well as three access functions by which your code can
manipulate the Calculator: getButton, getText,
and setText.
- CalcTextGUI.
This class is sort of like a "wrapper" for the Calculator. It provides
the basic text functionality present in the Calculator interface (but not
the getButton() method), as well as some other convenient functions such
as appendText, clearScreen, and getValue.
CalcTextGUI contains a reference to the "real" Calculator object
(which is a separate object), and implements its functions by calling
methods of that Calculator object.
- CalculatorState.
This class holds state information for the calculator FSM. It records
such things as:
- Am I (in the middle of) reading a number?
- Have I seen the decimal point yet?
- Have I seen an operation that I'll do (just as soon as I get its
second operand)?
- What was its first operand, anyway?
and provides methods for accessing and changing this information
- ButtonObj. A
ButtonObj is a handler object for button events (sort
of like a java.awt.MouseListener is a handler class for mouse events).
It contains references to the CalcTextGUI and CalculatorState objects,
and has the method handleButton(), which may use these objects
to change the state and output of the calculator. ButtonObj is
extended by a number of subclasses (i.e., NumButtonObj, OpButtonObj, EqualButtonObj, DotButtonObj, and ClearButtonObj). Each of
these subclasses overrides handleButton(), and defines
its own version. This provides us with different behaviors for the
calculator depending on what type of button is pressed.
- ButtonHandler. Just
as in the Calculator lab, this is a self-animating object (the only
self-animating object among the objects described here, in fact) that
takes care of getting the button pressed from the Calculator, and
dispatches them to the appropriate ButtonObj object.
The program runs as follows:
At the start, ButtonHandler receives a Calculator object
from the system through the constructor. Inside the constructor, it creates exactly one
CalcTextGUI, and one CalculatorState object. It then
creates a number of different ButtonObj objects passing the
CalcTextGUI and CalculatorState objects to them through their constructors.
A separate ButtonObj is created for each button. (Each of the
numeric buttons, '0' to '9', for example, get their own
NumButtonObj, but each initialized with the appropriate number.)
These buttons are stored in buttonObjs, an array of
ButtonObj, under their corresponding indices. For example, an
instance of ClearButtonObj is stored in
buttonObjs[Calculator.CLEAR]. At the end of the constructor, the
Thread spirit is created and started. This Thread then starts
executing run().
Inside run(), we have a while( true ) loop that gets the
next input pressed by calling the Calculator object's getButton() method, and
then effectively switches on the input received. This is similar to the "event-driven"
implementation discussed in the Calculator lab
solutions. Unlike the Calculator solutions, however, the "switch"ing
here is done in an unsual way. Instead of using switch or
if, we simply call
this.buttonObjs[buttonID].handleButton();
(where buttonID is the button pressed) to call the
handleButton() of the appropriate ButtonObj object. Since each of
these objects implements handleButton() differently depending on
what particular subclass of ButtonObj they are, we can get different
behaviors in much the same way that we got different behaviors by calling
different handle...()
methods in the Calculator lab solutions. Polymorphism is neat, huh?
For more information on the details of the different classes, please refer
to the javadoc documentation, and of course, to
the documented source code.
This course is a part of Lynn Andrea Stein's Rethinking CS101 project at
the MIT AI Lab and the Department of Electrical Engineering and
Computer Science at the Massachusetts
Institute of Technology.
Questions or comments:
<cs101-webmaster@ai.mit.edu>
Last modified: Tue Oct 7 21:56:59 1997