Space

- Program Breakdown -



PURPOSE:

The purpose of this section of my journal is to illustrate how I chose to break down the problem of programming the specified Space simulation.

INITIAL STEP:

The first thing I did after receiving the program handout was to read it over a few times. This allowed me to become familiar with the assignment and what I was supposed to do. Also, it gave me a better understanding of what concepts were being covered so I could review from my lecture slides or by asking a TA on hours the concepts that I was unfamiliar with.

Once I was clear on these concepts I decided to emply a method that the TAs showed us in the Help Session, I decided to circle all nouns and verbs from the program spec. Why did I do this? I thought (and they told me!), that it would help me think about the problem in terms of objects and their attributes and capabilities. Also, it helped me start to understand the problem better. Here is a list of nouns and verbs that I came up with:

NounsVerbs
space move (forward, backward)
simulation turn (left, right)
user activate
space shipfire
Attackershine
Explorerpress
weapon change color
light
shape
input device
mouse
keys

Once I had concretely found all the objects in the specification I decided to examine them to see if they all made sense and if there existed any relationships between them.

space: This is the place where the ships will move around in.

simulation: This refers to the entire program. Might be like the applet.

user: That's me! This is the person who is manipulating the simulation.

space ship: This is what the user moves around the screen. The ship must be able to be activated, move, turn, and change its color.

weapon: This is fired when an Attacker is activated.

light: This is shined when an Explorer is activated.

shape: This is something all ships must have. This represents how the ship will look on screen.

input device: This is how the user tells a ship to do something. This can either be through mouse interaction or through key presses.

One thing I discovered in doing this is that by the time I had finished going through the list of nouns I had already covered all of the verbs. This suggested to me that these objects and actions were all related in some way. Some nouns were related to other nouns in that they were preoperties of other things. Other noun-noun relations I encountered where placement relationships (a ship moves in space) and creation relationships (an Attacker fires a weapon).

And through my noun-noun relationships I discovered noun-verb relationships as you can see above. As well as though I say that by pressing keys or buttons the user could move, turn and activate a ship. Once I had a decent idea of how my objects would interact I decided to try my hand at a design using OMT.

FIRST DESIGN ATTEMPT:

The first thing that I noticed was wrong with my design was that the mouse class did not have any relationships with any other classes. It also did not do anything, which is not what I thought it should do when I read the specification and determined what my classes should be doing. Once I realized this I noticed that I had incorrectly decided that a button was an input device when I really meant that the mouse should be an input device. This is true in the real world but is it true in our modelling world, or more importantly in GP?

The answer turned out to be no. A mouse is something that is used by the physical user to press a button. So in fact the button is what is really telling the ship to do something, not the mouse. With my initial fears about the mouse not being included quelled I decided to examine the rest of my design.

The next thing I noticed was that my Ship class, my Attacker class and my Explorer class all had the same methods and the same references. In fact the only difference between the two was that the Attacker had a reference to a Weapon and the Explorer had a reference to the Light. Also, I realized that at any given time I would only be manipulating an Attacker or an Explorer; I would never be manipulating a Ship itself.

Seeing this I decided to turn to the lecture foils on inheritance and encapsulation. After reading through these a few times and talking to by best friend Peter, I decided to make the Ship class be a generic, or abstract as they call it in Java, superclass and to make the Attacker and Explorer classes subclasses of it. Doing this would allow me to move all of the would-be repeated code to this superclass and would save me time when I eventually wrote the code. Also, having somewhat understood what the TAs said about polymorphism in the MOTIVATION section of the handout, I realized that this would allow my input devices (keys and buttons) to interact with a generic ship. Whenever I changed the ship during the simulation I wouldn't have to change how the input devices interacted with them.

SECOND DESIGN ATTEMPT:

Feeling pretty good about my initial attempts at designing this system I took my design to a TA and the first thing they asked me (they are always asking me questions instead of telling me things!) was how my different subclasses of Ship were going to move differently. I thought about it for a second and blurted out "because that is what they do!" To which they replied "true, but you aren't showing that in this diagram. According to what you have here allships move in exactly the same way. If you wanted to show that they moved differently what would you do?" Still confused I said that I would specify that an Attacker moved fast while an Explorer moved slowly.

The TA of course asked me then how I would show that. I told them I would add methods MoveFast() and MoveSlow() to the classes respectively. Th TA smiled and asked how my input devices would know what methods to call when they were pressed. Suddenly a light bulb went off in my mind and I thanked the TA (Jenna is a really good TA by the way) and ran downstairs to continue my design efforts.

The epiphany that I had come to while at hours was a realization of what had been said in the handout. All ships know how to move, but they all move differently. My abstract Ship class could have an abstract method called Move() which the subclasses could overide to execute whichever code they wanted to execute. This way my Attackers and Explorers could all move in any way they pleased! (As a side note I then noticed that the Ships had to Thrust and Dethrust so I modified my Move() method into these two separate methods.)

Feeling pretty solid about how my ships would act I decided to work on some more of the user interaction. How would my user select the color of the ships? Moreover, once a color was selected how would we be able to actually tell the current ship to change its color? If I would be able to change ships at runtime would I then have to tell my buttons for changing color about the new ship? This seemed awfully complicated to me but I decided that it was probably the only way to do it. Also, eventhough I had thought by being polymorphic it would be easy for me to have my input devices act on the current ship I realized that I would have the same problem here. Everytime I changed the ship I would have to tell my current input device about the new ship. Also, if I ever changed the input device, which the spec says I have to, I would have to tell it about the current ship. So now my Space class would have to have a reference to the current input device as well as the ColorChooser. My design was becoming very complex.

My head was swimming at this point. As assignment that seemed really easy at the beginning was now looking like it was going to take forever. Everything was so complicated. Eventhough I was ready to give in I decided I would try a new design that incorporated my color chooser.

THIRD DESIGN ATTEMPT:

Looking carefully at this new design you may notice that some of the lines between boxes have changed form. Instead of ending in diamonds they end in arrows. This change from aggregation (containment) to association was because I realized that these objects did not physically contain the ones they were presently containing. For example, a key does not contain a ship in any sense. However, it does associate with it in that it will tell the ship to do things. I owe this change to the insight of my friend Rocco.

It seemed to me now that my Space object was getting way too complicated for something that was just supposed to model what the Ships moved around in. I then decided to move the responsibility of magaing all of the choosers to the Simulation object. I also realized that since I had moved up a layer I know needed the simulation to know about the current Ship so I added a reference there. I also decided that the Simulation class should graphically contain all of the choosers instead of just associating them. After making this decision I realized that my Simulation class was now assuming the role of being a large GUI managing class.

Being a properly motivated student (that's what the TAs call me) I decided to run my design by the TAs again. After discussing some of the decisions I had made, which I have just told you all about, the TA (this time it was John) told me my design was way too complex. Too complex my butt! This was a hard assignment so no kidding that my design was complex. The TA assured me that yes, it was a hard assignment, but that that did not mean my design had to be complex. I asked the TA what he meant and he told me that my chooser/simulation relationship was going to cause me alot of trouble when I went to implement my design. He said that it was confusing to have so many objects know about so many other extraneous objects when their purpose was simple.

Having no idea what John had just said I asked him to simplify. He used a very simple analogy which helped me tremendously. He asked me if my whole purpose in life was to be a garbage person, a sanitary technician if you will, would I need to know anything about Philosophy or higher math to get my job done. I said no way. He then told me that this particualr interaction between my choosers and simulation class was like this. What does a ColorChooser need to know about a Simulation class when all it wants to do is change the color of a Ship? Absolutely nothing we both agreed.

He then proceeded to point me to lecture on the Holder pattern. After remembering all that was said about using the Holder pattern I decided it was something I could use for my design. Effectively I would use this pattern to allow my multiple choosers access to my Ship class. This way whenever I changed the ship at runtime I wouldn't have to change the references of all my choosers; they could just have a reference to a ShipHolder and manipulate whichever ship was currently active. This seemingly new innovation (as I had cut class to go play frisbee with my buddies Tony and Racquel) made me very excited about design and my program!

Excitedly I changed my design to encorporate the Holder pattern.

FOURTH DESIGN ATTEMPT:

Now that I had a pretty robust design I decided it was time I start thinking about implementation. That is, what classes already existed for me, what could GP do for me, what would I have to write myself.

My Ships would have be to be a graphic of some sort since that was part of the specification. This would be easy, before where I had specified Shape I would just use a GP.Graphics.Shape. I was very happy to see that early on I had made a good design choice in having my Ship class contain a GP.Graphics.Shape instead of subclassing from one. This was one problem I was not going to have to deal with. I also found that all shapes in GP can be colored so that I wouldn't have to keep track of Color in my Ship class.

My Button would be GP.Components.Buttons.Push and would be very simple to write. My choosers could all be GP.Containers.RadioColumns or GP.Containers.RadioRows. I remembered this from when I wrote Swarm. My Weapon could be a GP.Graphic.Shape as could my Light.

As we had not tackled key input yet I needed to look at the GP Package Index to find out what I could use, or if GP even supported it (though I suspected it did since it was in the assignment specification). It took me awhile to find it but I found that we could use GP.Reactors.KeyInteractors to do this. I also noticed that I would need to have two types of buttons: Push buttons and Toggle buttons. All of my choosers would contain toggle buttons whereas the buttons which would control the Ship would have to be Push buttons.

(As a side note, I think someone should write a document that would help expedite this search for classes in GP. You know, like a tutorial or something.)

Starting to think about the buttons and input a little more made me realize that I would have to have something which managed my buttons which moved the ship. I decided to create a new class called MouseController which would do so. I would also want something similar to manage my keys so I created a class called KeyController. Afer these were setup I finalized their relationships to the ShipHolder and not to the actual Ship.

Finally I needed something for my Ships to fly around in. This was an easy choice -- I'd use the GP.Containers.Frame that we had come across so much in the past. At this point I realized that this class would not actually contain my Ship class at all, but would just allow it to draw itself there. I decided to model this non-relationship and took away the containment relationship in my design.

At this point I was feeling pretty optimistic about the assignment. Now it was time for some coding!

ON TO THE CODE:

This is the design that I took in with me when I went to code. I had come along way since my initial design and felt that through all of my struggling and successes with design I had a pretty good knowledge of how this assignment was supposed to be broken down and written. Coding, I surmised would be alot easier now that I knew what sort of relationships all of my objects would have. All I would have to do is deal with those "trivial implementation details" that the TAs are always sloughing off.


This page was last updated by Shoe on 03/03/98.
Comments or suggestions, should be sent to: ahs@cs.brown.edu
Space is copyright 1996-1998 by Andrew H. Schulak