Refactoring the Percolation Project

A project to simulate percolation through a porous material

Alyce Brady
Kalamazoo College

 


Getting Started

Overview

The Percolation program simulates a substance percolating through a porous material, such as water or gas percolating through the ground.  The simulation shows percolation through a vertical two-dimensional slice through the material, represented by a bounded grid.  At the beginning of the simulation, cells within the grid represent solid material or empty porous openings.  A percolating substance is added to the porous material; as the simultion runs, the percolating substance spreads to other empty cells.

Through a graphical user interface, the user can control how the simulation program is run, stepping through it one step at a time or running it for many steps until the Stop button is pressed.  In each step, the percolating substance seeps a little further if it can, moving one cell at a time in one or more directions.

Through the exercises in this project, you will be creating a class to represent solid material, and creating another class to represent a simple vertical percolator (a substance that sinks, or percolates down, but does not seep sideways nor percolate up).  In a follow-up to this lab, you will create a class that can seep sideways or down, but still obeys gravity and does not percolate up.

Classes

You will be using several classes provided for you, shown in the diagram below, as well as creating new classes of your own. 

object diagram

Downloading and compiling a skeleton version of the program:

  1. Download the zip file (Percolation.zip) for the Percolation Project, and unzip it. The starting code files described above are in the PercolationCode folder. (You can ignore the contents of the Instructions folder, which contains instructions for a different set of COMP 150 exercises.)
  2. Copy the files you looked at in the previous Reading Code exercise into the PercolationCode folder:
  3. Also download grid.jar, the Java archive library for the Grid Package, containing classes such as Grid, GridObject, and ColorBlock, upon which the Percolation Program is built.
    You will have to make sure your project knows about the grid.jar library. In BlueJ, you can create a +libs folder under the PercolationCode folder and put the jar file there, or you can specify its location in the Libraries tab of the Preferences or Properties dialog box (under BlueJ->Preferences, Tools->Preferences or File->Properties, depending on the version of BlueJ you are using).
  4. Within BlueJ, open the PercolationCode folder as a Non-BlueJ Project and compile it.

 

Becoming More Familiar with the Program and User Interface

In the next exercise you will run the Percolation program and become familiar with the functionality of its graphical user interface.

Understanding the SolidCell Class:

  1. Look over the SolidCell class, whose objects represent solid matter in the porous material. Every class that represents objects in a grid must inherit from the GridObject class, but in this case it does so indirectly: the SolidCell class extends the ColorBlock class, which extends GridObject.
        java.lang.object
          |
          +--edu.kzoo.grid.GridObject
                |
                +--edu.kzoo.grid.ColorBlock
                      |
                      +--SolidCell
    • Notice that the new SolidCell class does not need any new instance variables, since it inherits all the state it needs from ColorBlock and GridObject.
    • SolidCell has two different constructors: one which takes no parameters, and one which takes one parameter, a color. Since a ColorBlock expects to be told the color of the block, the constructor with no parameters will always create itself as a black block.
    • Finally, the SolidCell redefines the act method from GridObject. The inherited method does absolutely nothing, but the redefined version prints out a debugging message if debugging is turned on.

Analysis Questions:

(You do not need to formally write up and turn in the answers to the questions in this assignment, but if there are any you do not understand or to which you are unsure of the answers, you should be sure to follow up with your instructor or someone in the Collaboration Center.)

  1. Which superclass constructor is being invoked by the two calls to super in the SolidCell constructors?
  2. Where does the location method being called in act come from? Who is the "Hey, you!" object receiving that method? (Hint: look at the class documentation for the ColorBlock and GridObject classes.)
    Class documentation for all classes in the Grid Package can be found here.

 

Becoming familiar with the program:

Compile and run your percolation program.

Buttons:
  • Create a new grid using the appropriate button in the graphical user interface.
  • Using the Manually Populate Grid button, add a few solid cells to your grid.
    • How many types are available to you in the Type pull-down menu?
    • What happens when you click on an empty cell in the grid? What happens when you click on a grid location with a SolidCell in it?
    • What happens when you click the Done button?
    • What happens if you click on Manually Populate Grid when the grid already has some items in it?
  • Click on the Step Once button, the Step N Times button, and the Run button. What happens? What did you expect to happen? Why?
    Note: when you click on the Step Once button, the graphical user interface calls the step method in the program's controller object (SlowPercolationController), which calls the act method for all the cells in the grid. What does the SolidCell act method do?
  • What happens when you click on the Automatically Populate Grid button? What is the effect of choosing a density of 0%, 5%, 30%, 75%, or 100%?
  • What happens when you click on Manually Populate Grid after having automatically populated the grid? Why might this be useful?
File Menu:
  • Create a new grid using the File menu, not the New Grid button. Edit the grid, again using the File menu, and add some solid cells to your grid. Is the behavior any different from using the buttons?
  • Open the grid file called porousMaterialA.dat. (It should be in the same folder as your BlueJ project, along with several other data files and a folder called images.)
  • Edit the grid you opened to place a solid cell that cuts off one of the pathways from the top of the grid to the bottom.
  • Save your new, edited grid as porousMaterialA2.dat.
  • Test that you saved the file correctly by creating a new grid (to overwrite the current one) and then opening your saved file.
  • Open the other data files provided to you to see how they differ.
Percolator Objects:
  • Run the program a few more times, experimenting with adding different types of Percolation objects to the grid. Percolation objects should be added to the top row, as if they were starting at the surface of a porous material. Different types of objects will seep down through the material in different ways, especially when they encounter obstacles such as solid cells.

 

Refactoring the Percolation Project

The Percolation project as it exists so far suffers from quite a bit of duplicated code. This makes the code harder to read, reason about, and maintain. In particular, it has three classes that are nearly identical: the act method is exactly the same in all three and the percolateTo method is nearly the same. The classes differ substantially only in their getPercolationLocation and duplicate methods. An improvement would be to move the shared methods into an abstract superclass that all three Percolators can inherit from.

Refactoring the Percolation Project:

  1. Currently the VerticalPercolator, GravitationalPercolator, and AllDirectionPercolator, are all subclasses of the GridObject class. Modify these classes so that they extend AbstractPercolator instead. The return type for their duplicate methods could also be AbstractPercolator,
  2. Replace the act method in AbstractPercolator with the method from one of the concrete Percolotor classes, and move the percolateTo method to AbstractPercolator also. Then delete those from the other classes.
  3. Add an abstract method called duplicate to the AbstractPercolator. The return type for this method will be AbstractPercolator. You will also need to add an abstract getPercolationLocations method. Do not delete these methods from the concrete classes.
  4. Notice that there is duplicated code even within the getPercolationLocations methods. Create a version of that method in AbstractPercolator that includes the common behavior. In any classes that do something beyond the common behavior, you can start by calling super.getPercolationLocations() to get a starter list and then add aditional locations as appropriate. For any class that does not do anything beyond the common behavior, there is no need to include (override) the method at all.
  5. Test the modified version of your program. All percolators should work exactly the same way they did before you made your changes.

 

Sidenote: Using Other Images

Grid package applications provide a relatively easy way to associate a picture with a class, so that every object of the class in a grid is represented by the same picture.

Using images to represent solid cells:

  • If you want, you can change the code in the PercolationApp class to use any of the files in the images folder in the Percolation project.
  • Alternative: You can also get a Grid Package program to use an image for objects of a class by placing an image with the same name as the class in the same directory as the BlueJ package file. For example, you could copy the marb1.gif file to the same directory as the class and change its name to SolidCell.gif.

 

Sidenote: Debugging

Often when you write a program, it is useful to keep track of some information as you go. You can do this by printing that information. On the other hand, once you know you have your program working you will not want extraneous messages coming out when you run it. The Grid Package Debug class provides a handy way to put print statements in your code that will only print out only when you want them to, usually during debugging.

Debugging:

  • You already discovered in Exercise 3 that solid cells don't do anything when you click on the Step Once button, even though their act method is being called each time.
  • Edit the PercolationApp class and find the commented-out code that turns debugging on. Uncomment it and run your program. Do you see different behavior?
  • Before running the program again, click in the BlueJ terminal window and then choose Clear from the Options menu.