View this PageEdit this PageAttachments to this PageHistory of this PageHomeRecent ChangesSearch the SwikiHelp Guide
Hotspots: Admin Pages | Turn-in Site |
Current Links: Cases Final Project Summer 2007

Milestone 3: Design everything.

This milestone seems a lot easier than it actually is. The good thing about this fact is that the harder you
work here (as with all development projects), the easier it is to work later on down the road. Our team had
a very simple design, and thus it's elegance. I will display our UML and describe our design further down,
but first some advice for future students.

This is an obvious step yet still many groups overlook it. When you do this, get everyone involved and think
about who's going to be doing what. I suggest assigning one person to the GUI, one person to the model, and
two people to the network. Networking in Squeak sucks (unless you use our team's code, which is highly
recommended, as it is perfect).

This is very important. It helps group members pick up their responsibilities quickly and makes it easy for
everyone to move along more gracefully from programming one class to another. I came into this group late,
(my three team members dropped after the first test, and a member of this team dropped, too. Incidentally,
they got B's on the test and I failed it, but that's a whole other story) and the design was simple enough
that I was able to jump right in programming on the model and I ended up finishing first, even though when
I started I had no clue where to start.

We required most of our classes to be done by two people. That way you can ensure that work is being done
gradually on each class, and no one is thrown a huge pile of responsiblity. As it turned out, one person
did the majority of the work on each class. At the beginning we were not sure who that person would be,
so we just assigned the class to the two people whom it seemed most feasible to work on.

Our timeline had dates on it. We had a spot for each day until the project was due. In retrospect, this was
pointless. We ended up writing all of the classes at the same time, instead of working on one class, finishing
it, and then moving on to another class. Instead, when you make your timeline, use functionalities instead of
class names. For example, in our project, we should have said, "First we'll get clients to be able to talk to
the server. Second we'll get people's information on the server. Third we'll get people moving around... etc."
Saying that you're going to finish the ClientModel and then start working on the ServerModel is naive.



And now for our design. Below is our UML. I said earlier that it is very simple, and it is a lot smaller than
other teams', as you will see if you browse around. One of the things you might notice is that we have one
class representing all of the GUI. This you probably won't want to do. Our GUI had several different screens
since it was developed for the PDA (we didn't create a separate GUI for the desktop, that seemed like too
much unnecessary work). We would have liked to have had separate classes for each screen, but as it was,
the only three of us that actually worked on the project were up all night the night M4 was due programming
the GUI, so balls to more than one class it was... we'd do that later (which we didn't).
Note: All fields listed as arrays were actually OrderedCollections (ArrayLists from Java). Sure, some of them
would have been better as Dictionarys (hashtables), but we didn't know those weren't slow until later on in
the course. FYI: OrderedCollections are used for iterating on all elements and Dictionarys are used for
Accessing a single element.

Uploaded Image: design.jpg

The way I like to think our program works is that the GUI calls functions on the ClientModel, which then calls
a corresponding method on the Server, which then updates the Person that's connected to the ClientModel, which
may or may not call another method back on the Client to give the ClientModel some information on the server.
Since we were dealing with PDAs which have a limited amount of memory, we decided to use information packets
which contained all of the data that a ClientModel would want to know, but none of the data that it wouldn't
need to know (like the methods that are in that class, etc.). The way the above description works is that
the Client gets a connection to the Server, the Server holds all of the people and places, and the Persons
hold a connection to their clients. The way connections work is that our network allows any class with a
connection to another to call a method on the class it's connected to as if it had an instance of that class.
I'm not sure how this works exactly (see our Networking cases page for more on that) but it has something to
do with overwriting the DoesNotUnderstad method (yeah, great idea isn't it?).

ClientModel - This class has all of the functions that the GUI would call (everything the user should expect
to do), and all of the functions a Person would call on the Client (receiving info packets, etc.). Sometimes
the Server calls a method on the Client directly through it's instance of the Person. The others list and the
friends list are similar, but they are for two different things. The others list is a list of everyone else
in the same Place as you. The friends list was used as a temporary list of PersonInfos (bad design, but it was
a last minute hack). When you viewed anyone's friends, those PersonInfos would be put into the friends list.
When you searched for other people with a specific interest, those PersonInfos would also be put into the
friends list.

ServerModel - This class mainly had functions that the ClientModel called. It also had some internal functions
that we used such as personAt: which took in a personID (each person had their own unique ID number which was
given to them when the logged onto the server) and returned the instance of that person in the list of all
Persons. NewConnection: was the function that was called when someone logged onto the server. This is where
all of the Person and PersonInfo instances were initialized (and the uniqueIDs assigned).

Person - This class held all of the methods that dealt with changing information on this Person. The server
would access some of these methods and alter the data on this Person itself when dealing with multiple people,
but the Person would change its own data (via a function call from the server) when it was the only thing being
changed.

Place - This class was a recursive class. At the top level was the rootPlace (a method on the server which
returned the first place added). And this place contained all of the other places so that when a user moves
into a new place, the view zooms into that place and the user can see everyone in that subplace. As such, all
of the methods in this class were recursive (thank you cs1321x). This class held only PersonInfos. At first
we thought that it should hold refrences to the Person, but then we decided that the Server was just going to
pull data from the Place and apply changes to Persons itself, which was very effective. If you look at our code,
none of our functions are excessively long, which is an ideal preached by abstractness, and that's exactly what
we strived to obtain: Complete Abstractivitizationess(c). The network is abstracted out (so much so that we
recommend you use it in your projects), the client's, server's, persons', and places' responsibilities are
abstracted away from each other, and the GUI only knows about the fields that are in the ClientModel.

Seriously, not only was our design the best (and several groups told us this after the design roundtable), but
our program was the best, too. My only regret is that not too many people can acknowledge the latter fact
because Brian screwed up our final demo, and I hate him for it. He sucks. "NOTE: I, Brian, did not screw up the demo Squeak did."

Link to this Page