AP Case Study Overview Barbara Ericson ericson@cc.gatech.edu March 2006 Georgia Institute of Technology Learning Goals • Understand the case-study design and implementation – What is the purpose of the case study? – What are the classes? – How to extend the case study? – What is good about the design? – How to study for the exam? Georgia Institute of Technology Purpose • Provide a larger example of an object-oriented program – To use • Run the program • Look at the code and modify it – To learn from • An example of good design, documentation, and code • Discuss design issues – To extend • Deepen understanding of inheritance and polymorphism by using them to extend a program Georgia Institute of Technology Example Simulation • A simulation of a realworld environment – A simulation of fish in a lake • Job simulation – Master / apprentice • Pat is learning from Jamie about how to do Object-Oriented design Georgia Institute of Technology Setting the Stage • Pat, gets a summer job programming for marine biologists • Needs to modify an existing program written by Jamie – Runs the program – Tries to understand it – Designs, codes, and tests modifications – The narrative is her report Georgia Institute of Technology What is in the Case Study? • Source and class files for main classes – Jar files for other classes – In Code directory • Narrative – Report by Pat – In Narrative directory • Data files for setting up simulations – In DataFiles directory • Javadoc html documentation – In Documentation directory • How to run in several development environments – In ExecutionInformation directory Georgia Institute of Technology Narrative Chapters 1. Pat’s exploration • • Run the program Think about what is happening 2. Explanation of the classes by Jamie 3. Modifying behavior • Adding breeding and dying 4. Adding inheritance (specialization) • Adding slow and darter fish 5. Modifying the environment • Unbounded environment Georgia Institute of Technology What is the Goal of the Program? • “I worked on a simulation of fish moving in a relatively small body of water, such as a lake.” – First fish can only move – Later the fish can breed and die (Chapter 3) – Later add slow fish and darter fish (Chapter 4) – Later add other environments (Chapter 5) Georgia Institute of Technology Chapter 1 - Exploration • Run the main methods in the simple demos – SimpleMBSDemo1, SimpleMBSDemo2 • Underline the nouns and verbs in the specification on the next slide • Do a walk-through with students acting as fish (blindfolded) and the environment – Who does what? • Use CRC cards to determine the Classes you might need Georgia Institute of Technology Chapter 1 – Analysis Exericse • The marine biology simulation case study is a simulation program designed to help marine biologists study fish movement in a small, bounded environment such as a lake or bay. – For modeling purposes, the biologists think of the environment as a rectangular grid, with fish moving from cell to cell in the grid. Each cell contains zero or one fish. Georgia Institute of Technology Fish in a Bounded Environment Georgia Institute of Technology Exploring the Code – Chapter 2 • In this chapter you get a guided tour of the code • What are the main classes and interfaces? – Simulation, Fish, Environment • What other classes and interfaces are there? – Locatable, Location, Direction, EnvDisplay, RandNumGenerator, Debug Georgia Institute of Technology Simulation Class • A simulation of fish would need a simulation class – To set up the simulation objects – To run the simulation • Usually a simulation will take place over time • So we need something to say that a unit of time has passed – A simulation time step Georgia Institute of Technology Fish Class • A simulation of fish would require a Fish class – What data does a fish need to know about itself? – What can fish do? Georgia Institute of Technology BoundedEnvironment Class • A simulation of fish in a bounded environment like a lake or bay – Does it matter if it is a lake or bay? – What is a boundedenvironment? – What data does the environment need to know about? – What can an environment do? Georgia Institute of Technology The First Simple Simulation • Create a bounded environment with a number of rows and columns • Create the fish and set their locations • Create the display class to display the simulation – SimpleMBSDisplay • Loop and tell each of the objects in the simulation to do something each time through the loop – Update the display to show the changes Georgia Institute of Technology The Second Simple Simulation • The driver – Creates an Environment object – Creates Fish objects – Creates an EnvDisplay object • SimpleMBSDisplay – Creates a Simulation object – Loops sending the step message to the simulation object Georgia Institute of Technology What happens during a step? Simulation object Environment object Fish object allObjec ts id environment is Empty objectAt color ge tDirection location ne ighborsOf add remove id dire ction environmen is InEnv color toString location id ac t dire ction environment is InEnv color toString Fish object ge tNeighbor (pa rtial list of methods) ste p Fish object recordMove location Fish object id ac t dire ction environment is InEnv color toString location ac t dire ction is InEnv toString ac t Georgia Institute of Technology EnvDisplay object showEnv Step Method public void step() { // Get all the fish in the environment and ask each // one to perform the actions it does in a timestep. Locatable[] theFishes = theEnv.allObjects(); for ( int index = 0; index < theFishes.length; index++ ) { ((Fish)theFishes[index]).act(); } theDisplay.showEnv(); Debug.println(theEnv.toString()); Debug.println("———— End of Timestep ————"); } Georgia Institute of Technology Debug Class • Used to handle messages for debugging – You can turn on debugging messages • turnOn() – You can turn off debugging messages • turnOff() – You can print messages when debugging is on • print(message) or println(message) – You can restore the previous state • restoreState() Georgia Institute of Technology Step Method Exercise • Why is the return type from the method allObjects() an array of Locatable objects? – Look at the Fish.java class – Look at the Locatable Javadoc documentation • Why do you need to cast to Fish before you send the message act? – Do Locatable objects have an act method? • Why do you need to send the message showEnv() to the EnvDisplay object? Georgia Institute of Technology What happens in the act method? • Originally it checks that the fish is in the environment – And if so sends the fish the move message • The move method invokes nextLocation() to get the new location to move to – which works with environment to get a random next location from the empty neighbors » Removes the location behind the fish • It checks if the new location is different from the old location – If so it calls changeLocation to do the move – It gets the new direction to face from the environment – It calls changeDirection to use the new direction Georgia Institute of Technology Fish and Environment • Fish and environment have a bi-directional association <<interface>> Environment – A fish keeps track of the environment it is in – The environment keeps track of the Locatable objects in it – Fish are locatable objects • When a fish object is created – It asks the environment to add the fish • When a fish object moves – It needs to update the environment Georgia Institute of Technology <<interface>> Locatable Fish The Move Method /** Moves this fish in its environment. **/ protected void move() { // Find a location to move to. Debug.print("Fish " + toString() + " attempting to move. "); Location nextLoc = nextLocation(); // If the next location is different, move there. if ( ! nextLoc.equals(location()) ) { // Move to new location. Location oldLoc = location(); changeLocation(nextLoc); // Update direction in case fish had to turn to move. Direction newDir = environment().getDirection(oldLoc, nextLoc); changeDirection(newDir); Debug.println(" Moves to " + location() + direction()); } else Debug.println(" Does not move."); } Georgia Institute of Technology Move Method Exercise • Why does the fish have to work with the environment object to figure out where to move to? – Why does the fish class determine which neighbors are empty? • When does the environment record that the fish changed location? • Why are the locations checked to be equal using equals() not ==? • Why does the environment determine the new direction for the fish to face? • Why doesn’t the code check if the new direction is different from the old direction before changing it? • Why can’t fish go backwards? Georgia Institute of Technology Partial Class Diagram Georgia Institute of Technology Location Class • Stores row and column information – Implements Comparable • A location is less than another location when it is above and to the left of the other 0 – Overrides equals • True if the row and column values are the same 0 1 2 Georgia Institute of Technology 1 2 3 4 Direction Class • Represents a direction – Has constants for the compass directions – Can also create using degrees • 0 is North • 90 is East – Can get a new direction • toRight, toLeft, reverse – Overrides equals Georgia Institute of Technology RandNumGenerator Class • Class used to create and hold a pseudorandom number generator – java.util.Random • Used to pick something – The color for a fish – The location to move to • Used to get consistent results – Especially if you use the same seed Georgia Institute of Technology Interfaces Used • Locatable (object with a location) – Has a method to get a location – Used to allow you to put other types of objects in an environment • Environment (tracks locatable objects in a grid) – Has methods to add and return Locatable objects – Has methods to get neighbors of a location • Including a method to get a neighbor in a direction – Has methods to get the direction between two locations – Used to allow you to change the environment class (like switch to unbounded environment) • EnvDisplay (display an environment) – Has a method to show the environment – Used to allow different display classes Georgia Institute of Technology Adding Breeding and Dying – Ch 3 • Problem Specification: A fish should ... – have a 1 in 7 chance of breeding, – breed into all empty neighboring locations, – attempt to move when it does not breed, – never move backwards, and – have a 1 in 5 chance of dying after it has bred or moved. Georgia Institute of Technology Modified Act Algorithm If this fish isn’t in the environment return if a random number from 0-1 is in 1/7 range try to breed into all empty neighbors If breeding failed try to move to an empty neighbor but still can’t move backwards If a random number from 0-1 is in 1/5 range die Georgia Institute of Technology Breed Algorithm • Get a list of empty neighboring locations • For each location in the list – Create a new fish at that location • Use the same environment as the parent • Remember than the constructor for fish adds the fish to the environment • Use the same color as the parent • To make it easier for subclasses to create a child that is the same type – Use a protected method generateChild(loc) Georgia Institute of Technology Die Algorithm • The only reference to a fish object is in the Environment – So remove the fish from the environment • Sets the reference to the fish to null – Then it can be garbage collected whenever garbage collection runs Georgia Institute of Technology Breeding and Dying Exercise • How would you handle increasing the odds that a fish will die as it ages? • How would you handle requiring a male and female to be in close contact before a female fish can breed? – How about if a fish has to be a certain age before it can breed? • How would you randomly assign the dying probability? Georgia Institute of Technology Advanced Simulations • Use MBSGUI – Open, create, edit and save environment files using the File menu – Modify the random number generation using the Seed menu – Modify what Run does with the Run menu – Zoom in or out with the View menu Georgia Institute of Technology Edit the Environment • In the File menu click Edit environment • You can add new fish by picking the type of fish and color – and then clicking in a grid location – You can save the result as an environment file Georgia Institute of Technology Adding New Types of Fish – Chapter 4 • Darter Fish – A darter fish darts two cells forward if both the first and second cells in front of it are empty. If the first cell is empty but the second cell is not, then the darter fish moves forward only one space. If the first cell is not empty, then the darter reverses its direction but does not change its location. • Slow Fish – A slow fish moves so slowly that, even when it does not breed, it only has a 1 in 5 chance of moving. Georgia Institute of Technology Using Inheritance • Darter Fish and Slow Fish are both types of Fish – They meet the substitution test – They have the same attributes and operations • But they specialize behavior – So some methods will be overridden • What method or methods would you override for each new type of Fish? Georgia Institute of Technology Darter Fish Changes • Change the definition of nextLocation – If the two locations ahead are both empty • Return the location two positions ahead – If the location just one ahead is empty but the next is filled • Return the location one ahead – If the first position ahead is filled • Return the current location • In move if the new location equals the current location – Reverse the direction • Modify generateChild to create a DarterFish • Create constructors using super() to initialize inherited private fields Georgia Institute of Technology Darter Fish and Dynamic Binding • The DarterFish class needs to override move, nextLocation, and generateChild – When a DarterFish object gets an act message it doesn’t find one in DarterFish so it calls the one in Fish – When it needs to move it calls the one in DarterFish Georgia Institute of Technology Slow Fish Changes • Add an attribute that represents the probability of moving – 1/5 chance • Modify the nextLocation method to only move to a random empty neighbor – If a random number is in the 1/5 range • Modify generateChild to create a SlowFish • Create constructors – Using super to initialize inherited fields Georgia Institute of Technology Slow Fish and Dynamic Binding • The SlowFish class needs to override nextLocation and generateChild – When a SlowFish object gets an act message it doesn’t find one in SlowFish so it calls the one in Fish – When it needs the nextLocation it uses the one from SlowFish Georgia Institute of Technology Fish Types Exercise • What would you need to do to create fish that swam only diagonally? • What would you need to do to create fish that never die? • What would you need to do to create fish that only stay at the bottom two rows of the environment? • What would you need to do to create fish that only have one baby? Georgia Institute of Technology Adding Environment Types – Ch 5 • The original code used a BoundedEnv – Represents a rectangular bounded environment like a lake or a bay • Pat is asked to add an UnboundedEnv – To represent a much larger area like an ocean – To represent areas that are not rectangular Georgia Institute of Technology BoundedEnv Class • Has a 2d array of Locatable objects – Fast to check if a location is empty or get an object at a location • array[loc.row()][loc.col()] – Slow to create an array of all objects • Has to loop through the 2d array and if there is an object at that location add it to the array to return • Inherits from SquareEnvironment – Abstract class that defines an environment with square cells Georgia Institute of Technology UnboundedEnv Class • Stores a list of objects in the environment – As an ArrayList • Takes up less space for large environments – No space saved for “empty” locations – Slow to find an object at a location • Must search the list to see if any of the objects are at the location – Fast to return an array of all objects in the list • Can use toArray() • Inherits from SquareEnvironment Georgia Institute of Technology Array versus ArrayList Fixed size once created Can grow and shrink Can contain objects and primitives Can only contain objects Must declare element type Element type is object Fish[] myArray = new Fish[15]; ArrayList myList = new ArrayList(); myArray[index] = new Fish(loc); myList.add(new Fish(loc)); Fish f = myArray[index]; Fish f = (Fish) myList.get(index); for ( int k = 0; for ( int k = 0; k < myList.size(); k++ ) k < myArray.length; System.out.println(myList.get( k++ ) k)); System.out.println( myArray[index]); Georgia Institute of Technology UnboundedEnv Details • Returns -1 for the number of rows and columns since it is unbounded – Another idea would have been to move that out of the interface and into BoundedEnv • Must search through the ArrayList for objectAt(loc) – Compare the current object’s location to the passed loc using equals • Checks that there isn’t more than one object at the old or new location – For recordMove() Georgia Institute of Technology Running with UnboundedEnv • Use data files from DataFiles\Unbounded EnvDataFiles • The display will show the fish with 0,0 at the top left – You can use the scroll bars to see the fish that have moved beyond the original display area Georgia Institute of Technology UnboundedEnv Exercises • The same data file will result in different fish configurations for a BoundedEnv versus the UnboundedEnv – And not just because there is no boundary so there are more places to move to • Do a fish simulation with students acting as fish – And change the order they are asked to move • Do they end up in the same location after each step? Georgia Institute of Technology Extensions to UnboundedEnv • Modify UnboundedEnv to make it easy to find an object at a location – Use a java.util.TreeMap which maps a Location object to a Locatable object – And still keeps the keys in sorted order by Location • What is the performance difference for objectAt(loc)? • Do you get more consistent test behavior? Georgia Institute of Technology Map Interfaces and Classes <<interface>> Map HashMap Hashtable <<interface>> SortedMap TreeMap Georgia Institute of Technology Map Methods • Add an value to the map for the key Object put(Object key,Object value); // optional • Get a value for a key Object get(Object key); • Remove the value with the key Object remove (Object key); // optional • Check if the key is in the map boolean containsKey(Object key); • Check if the value is in the map boolean containsValue(Object value); • Remove all objects from the map void clear(); Georgia Institute of Technology Looping Through a Map • Get a set of the keys Set keySet = map.keySet(); • Get an iterator on the key set Iterator iterator = keySet.iterator(); • Loop till no more items in the iterator while (iterator.hasNext()) { key = (String) iterator.next(); value = (String) map.get(key); System.out.println(“key is “ + key + “ value is “ + value; } Georgia Institute of Technology Which Collection Should you Use? • List - objects in order with duplicates allowed – ArrayList - not thread-safe so fastest – Vector - thread-safe – LinkedList - best when frequent insertions and deletions in the list • Set - no order and no duplicates allowed – HashSet - not sorted – TreeSet - sorted based on Comparable interface • Map – HashMap - not thread-safe – Hashtable - thread-safe – TreeMap - keys are sorted Georgia Institute of Technology What is good about the case study? • Models good design, documentation, and coding practices • Larger group of classes than students often encounter – So plenty to learn from • Uses a compelling problem – Creating a simulation for scientist • Context for design discussions – Students learn by changing existing code Georgia Institute of Technology Studying for the Exam • Know the classes and their responsibilities • Understand the code for the relevant classes • Understand how Fish and Environment work together – What happens when fish are created, move, breed, and die • Understand how to create subclasses of Fish • Understand the design decisions and tradeoffs • Understand inheritance and polymorphism Georgia Institute of Technology Graphical User Interface Help • Click on Help and then Help again • Contains instructions for customizing the MBSGUI – Change how fish are displayed – Add new types of fish – Add new types of environments – Add a menu to control breeding and dying Georgia Institute of Technology Summary • The case study is provided as an example of a larger, well designed object-oriented program – With distributed responsibility – With interfaces to allow different classes to be “plugged-in” by implementing the interfaces – With extensions to fish and environment • Promotes design discussion and nontrivial test questions Georgia Institute of Technology