
Captain Picard and Commander Riker are on a diplomatic mission to discuss
the possibility of the Smoltoks joining the Federation. The Smoltoks have
sent two representatives (Coad and Nicola) to meet Picard and Riker. The
Smoltoks are an unusual race in that they have an elaborate protocol for
sitting down before an important meeting. This protocol is discussed in
more detail below. Naturally, Picard and Riker have been trained in the
protocol.
Well, the most obvious candidates for classes are the people: the Humans
and the Smoltoks. Picard, Riker, Coad, and Nicola will be instances of their
respective classes. What sort of variables/methods will we want? Well, Humans
have a name and a rank, like "Captain". Should we make Captain
a subclass of Human? Or maybe we should have another class called StarfleetOfficer?
So what happens if Picard is an instance of the Captain class and he gets
promoted to Admiral? Now Picard is in the wrong part of the class hierarchy.
Do we make an new Picard derived from Admiral and destroy the old Picard?
That doesn't seem right. We can't go changing the class hierarchy every
time someone is promoted. A person's rank must be just a variable--a temporary
classification--let's not make it subclass. You can make a similar argument
for a person's job (i.e. StarfleetOfficer). A person's job doesn't really
matter for the situation we've been given, so let's just leave it out entirely.
So far we've got name and rank for a Human. But wait--Smoltoks also have
a name and rank. Let's make a superclass called Lifeform for their commonalities.
Hey - what if we just made everything an instance of Lifeform? Do we really
need separate classes for Humans and Smoltoks? What if we just had a variable
for race? There is at least one major difference: their protocol for offering
their chair to someone else. The rules are:
We could handle this by just testing the race variable in the offerChair
method. [This is a classic dilemma in OOA/OOD: test variable vs.
separate class.] I'm going to argue here that separate classes make more
sense. Even though this is the only difference I can think of right now,
I've got a feeling that there could be others. Also, it makes it easier
to add other races (i.e. Klingon) later if necessary.
We're going to have to compare ranks at some point and Humans and Smoltoks
don't use the same ranking system. Let's also store some numeric representation
of the rank to make things easier to compare. (Should rank be a class with
two variables: name and index? I think you can make a reasonable argument
either way. I'm going to say no, for simplicity's sake.)
Are there any other classes needed? Well, we could make a Chair class.
Yes, I think we're going to need that so that we can tell who is in what
chair and what chairs are empty. Consider the alternative: a variable in
each lifeform that tells what number chair they are in. How do we represent
empty chairs? Does a chair only exist once someone sits in it? No, chairs
should definitely be objects.
Let's try to formalize this a little more by doing some object scripts:
Which gives us the diagram:

Two important things to note in the above diagram. First, the
Lifeform class is
shown as an abstract class. We will not create any instances of
Lifeforms. In the
Lifeform class there is shown a offerChairTo: method which is abstract.
Any subclass
of Lifeform (Human and Smoltok in our example) must implement its own
version of offerChairTo:
Secondly, we will almost certainly need an initialize method in both
Human and Smoltok
classes. The rule of thumb is that initialize methods are not generally
shown on the OOA
class diagrams, but they're necessary at OOD time.
Now, in more detail:
(aLifeform isMemberOf: Human)This evaluates
ifTrue:[ ...your code...] ifFalse: [ ...your code... ].
This is your part. The OOA/OOD above does not contain every detail of
what you need to do, but it's pretty close. Here's a set of commands to
test your code.
|picard riker coad nicola chair1 chair2 chair3 chair4 |
riker := Human new initialize: 'Riker' rankString: 'Commander' rankIndex: 2.
picard := Human new initialize: 'Picard' rankString: 'Captain' rankIndex: 1.
chair1 := Chair new initialize:1.
chair2 := Chair new initialize:2.
chair3 := Chair new initialize:3.
chair4 := Chair new initialize:4.
riker sitDown: chair1.
riker offerChairTo: picard.
riker sitDown: chair1.
picard offerChairTo: riker.
riker sitDown: chair2.
chair1 showOccupant.
chair2 showOccupant.
coad := Smoltok new initialize: 'Coad' rankString: 'Alpha' rankIndex: 1.
nicola:= Smoltok new initialize: 'Nicola' rankString: 'Gamma' rankIndex: 3.
nicola sitDown: chair3.
nicola offerChairTo: coad.
coad offerChairTo: riker.
nicola sitDown: chair3.
nicola sitDown: chair4.
nicola offerChairTo: picard.
nicola offerChairTo: riker.
coad sitDown: chair2.
coad offerChairTo: nicola.
nicola sitDown: chair1.
chair1 showOccupant.
chair2 showOccupant.
chair3 showOccupant.
chair4 showOccupant.
If all is working correctly, you should get the following on the transcript:
Riker: It feels good to sit down.
Riker: Please take my chair, Captain Picard
Picard: It feels good to sit down.
Riker: Sorry for sitting on you, Captain Picard
Picard: Find another chair, Commander Riker
Riker: It feels good to sit down.
Chair1: Picard
Chair2: Riker
Nicola: It feels good to sit down.
Nicola: Please take my chair, Alpha Coad
Coad: It feels good to sit down.
Coad: Please take my chair, Commander Riker
Riker: It feels good to sit down.
Nicola: Sorry for sitting on you, Commander Riker
Nicola: It feels good to sit down.
Nicola: Please take my chair, Captain Picard
Picard: It feels good to sit down.
Nicola: Oops, I'm not sitting down yet.
Coad: It feels good to sit down.
Coad: Find another chair, Gamma Nicola
Nicola: It feels good to sit down.
Chair1: Nicola
Chair2: Coad
Chair3: Riker
Chair4: Picard
Debugging hint: use the "chair showOccupant." method to help
you check who is in the chairs at various points.
Create a new category in the leftmost pane of the smalltalk browser called
StarTrek. Then create the new classes (Chair, Lifeform, Human and Smoltok)
you need in the StarTrek category. Create the methods previously discussed
in each of the classes and test your code with the above test script (Hint, you
don't need to re-type this test code, you can just cut and paste it from the
Netscape window).
FileOut the entire StarTrek category. If you do this correctly,
you should end up with a StarTrek.st file in you current directory.
Open up the code in the text editor of your choice. (You can use
Squeak for this, too!). Highlight all the text and copy it. You can
find the commands you need in the Edit menu of most text editors.
You can now Turnin your code by going to the turnin page for your
appropriate section:
http://minnow.cc.gatech.edu/cs2390w98a (Section A)
http://minnow.cc.gatech.edu/cs2390w98b (Section B)
http://minnow.cc.gatech.edu/cs2390w98c (Section C)
http://minnow.cc.gatech.edu/cs2390w98d (Section D)
http://minnow.cc.gatech.edu/cs2390w98e (Section E)
http://minnow.cc.gatech.edu/cs2390w98f (Section F)
You will be prompted for a user name and password. Your user name is
your name as it appears on the CS2390 Home page. Your password is
your 9 digit social security or Student ID number WITHOUT DASHES!.
Click on the Turnin new project link. Select Lab3 in the Assignment menu.
You will now paste the code into the text area of the turnin web page.
Click on the Turnin button and you are done!
When you are done, EXIT FROM SQUEAK! Also, if
you saved any files to C:temp, don't forget to delete them before
you leave!
News Page | CS2390 Win'98 Home Page | CS2390 CoWeb | STABLE | BOOST
Questions/comments/concerns to guzdial@cc.gatech.edu
Page last updated 1/27/98; 3:11:48 PM