Midterm Sample Solution
Note: As with the other samples, this sample was created with
System Architect, a rather expensive and cruddy (but UML compliant) CASE
tool available on some CCS-maintained Andrew machines. If you can't get
Softera (also pretty cruddy) to work on your machine at home, you might
want to give this a try. I know for a fact that it's available on the first
three rows of the cluster in Cyert Hall.
Overview: Repair tracking system initial design
This document reflects approximately how I attacked this problem, in
step-by-step order. The notes associated with each problem are part
of the solution, and if you were doing a design like this for a real business,
you would probably want to present notes such as these with your diagrams.
Again, the emphasis here is on communication and readability
more than cleverness of notation.
Problem #1: Top-Level UML Use Case diagram for
the repair tracking system
In this system, the Mechanic actor is separated from the Analyst actor
to reflect the assumption that the two major operations in this system
would be done in different parts of the business by people with different
rights. This diagram has no detail at all on the sub-behaviors of
the system, and so only reflects that:
-
The system has exactly two capabilities, adding a repair and printing a
frequency-of-repair report
-
These capabilities may be utilized by two different types of users
Problem #2: First pass at classes for the repair
tracking system
The next step is a first-pass class diagram. This amounts to
identifying the classes in the system and then assigning the given list
of data to be tracked as attributes to the classes. This process
will usually cause one of a few sensations:
-
Data is "obviously" a property of one class: Most of the data that
needed to be tracked in this problem (date, cost, comments, etc.) belongs
in the RepairEvent class, so it made sense to put it there. Some
of you put cost on RepairTask instead; that was fine.
-
Data seems like it should go on a certain class, but the data is itself
another class: This problem required that the RepairTask and
RepairFacility related to the RepairEvent be recorded. But, since
these are non-primitive object types, they cannot be attributes.
So, associate them with the class instead.
-
Data doesn't seem to belong to any of the classes: In this problem,
Prof. Orgass's starting list of classes was sufficient to contain all of
the data as attributes, so you shouldn't have felt a burning desire to
add any more classes. But in general, there is sometimes data that
needs to be tracked at doesn't seem to belong to any of the classes you've
got. That means it's usually time to add a class. If you're
adding a lot of classes, you may need to rethink your entire strategy.
-
Data seems to belong to the relationship between classes rather
than a single class: This problem asked that you record the mileage
of each vehicle at the time of repair. Normally you might
think that mileage should be an attribute of Vehicle, but then only one
mileage, probably the latest, could be recorded. What you really
wanted was for the mileage of the Vehicle to be recorded for each repair
event. Hence, an association class was created that contained the
mileage.
Problem #3: Preconditions
and Postconditions for the two capabilities
Operation: |
addRepair (Date d, Vehicle v, RepairTask[] t, RepairFacility
f, Currency cost, boolean isRoutine, int mileage) |
Overview: |
The Add Repair Event use case occurs when the Mechanic wishes
to add record of a repair to a particular car. The Mechanic selects
the task and vehicle from the current store of data. The date and
facility are auto-entered by the GUI. The system then adds record
of the repair(s) that took place. |
Preconditions: |
-
Date must be valid
-
Vehicle, RepairTasks, RepairFacility are objects that already exist
-
cost is non-negative
-
mileage is non-negative and at least as large as any other mileage entry
for this vehicle
|
Postconditions: |
-
An unmodifiable RepairEvent object is created
-
It represents the repair event being added by having its attributes set
correctly
-
It is associated with the given vehicle, repair tasks, and facility
|
Operation: |
printRepairReport (String vehicleMake, String vehicleModel,
int year) |
Overview: |
The Print Report use case occurs when the Analyst wishes to
print a report of the number and type of repairs that are made to a particular
make, model, and year of car, in comparison to other kinds of cars.
(Some of you interpreted "frequency of repair" to mean the repairs made
to a single car, which was fine.) The system then generates the report,
changing no data in the system |
Preconditions: |
-
Year must be a valid model year
|
Postconditions: |
-
A report is generated of the collective repair records of all cars whose
make, model, and year match the specified criteria, or "no data available"
is given.
-
The system is not modified in any way. In other words, this operation
is read-only.
|
Problem #4: Methods and
collaborations for the repair tracking system
After writing a bit about what I expected the top-level operations
to be able to do, I added them as methods to the system, along with some
other methods that seemed necessary to support the work of the top-level
methods. Here is the second-pass class diagram:
These methods call each other as described by the following collaborations:
Note: Here, the variables VIN, description, cost, isRoutine,
mileage, and name are pulled from GUI fields. Date is the current
date. The results of the findVehicle, etc. calls are bound to variables
v, t, and f, which are then passed to addRepair.
Note: Here, ma, mo, and y are variables representing the make,
model, and year of the car type to be reported on, and are pulled from
GUI fields. The vehicles (if any) that match these descriptions are
determined during the call to findVehicles, and then each of those vehicles'
history is determined with calls to getRepairs. The results are then
compiled during printRepairReport and used to generate the report.