AP Computer Science
Marine Biology Case Study

Executive Summary of Part II

The Big Picture

The "story" of Part II is that biologists want to simulate fish movement in San Francisco Bay, or any other bounded environment that can be modeled as a rectangular grid (perhaps a lake near you).

What kinds of objects (in other words, what classes) do we have in this program? Well, we are modeling fish swimming in a bay, so we have a Fish class and an Environment class to represent those. The Environment is represented as a rectangular grid (an apmatrix) of locations. We also want to be able to display the fish and the environment, so we'll use a Display object that knows how to do this. Finally, what do we want to do with these objects? We want to simulate fish movement, so we have a Simulation object that controls the simulation. Since this is a C++ program, we also have a main function, found in fishsim.cpp.

Class Summary: We have many Fish objects, an Environment object, a Display object, and a Simulation object. We also have a main function.

There are a couple of other classes in the case study, but they play relatively minor roles. We'll come to them as we need them. [See below for more discussion of why there are separate Simulation and Display classes.]

What Do these Objects Do?

[Note: There are object diagrams on the College Board web site that illustrate these points.]

The Three "Gotchas"

It seems like this should be the whole story, but it's not. There are three important "gotchas" that make it a bit more complex.

Side Note: Why Have Separate Simulation and Display Classes?

Why do we need a separate Display class? Why don't fish and environments just know how to display themselves? This is, in fact, how we used to design objects in the early days of object-oriented programming, but over time people realized that putting the display behavior in the object can create problems. If you decide to change how you want to display things (for example, go from a text-based display to a graphical one), you have to change code all over the place. Now people recognize that it is a good idea to separate the way you model something from the way you display (or view) it. If we change to a graphical view, we just plug in a different Display class; we don't have to change the way we model the fish or the environment at all.

Similarly, it is a good idea to separate the program control from the basic objects we are modeling. For example, I might have classes that model a deck of cards. I could use them in a BlackJack game, a Gin Rummy game, or any of a number of other games that use decks of cards. This separation of model, view, and control is sometimes known as the MVC design pattern.

Summary: Model: Environment and Fish classes
View: Display class
Control: Simulation class

[Note to teachers: The control could also have been done fairly easily in main. The relative merits of these two design decisions could be the subject of an interesting class discussion.]

Side Note: Why Have A Separate Neighborhood Class?

The neighborhood of empty positions could have been implemented as an apvector, especially since the Neighborhood class does not provide any additional functionality. (This is unlike Environment, which is much more than just another name for an apmatrix.) On the other hand, a neighborhood could be implemented using a different data structure. A set, for example, would allow neighbors of neighbors to be added to the neighborhood without creating duplicates.

[Note to teachers: The relative merits of these design decisions could be the subject of an interesting class discussion, especially in a Data Structures course.]