Refactoring the Percolation Project
A project to simulate percolation through a
porous material
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.
PercolationApp
represents the application as a whole, and
contains the main
method.
(You will make several small modifications to this method in the
course of the lab, although most of your focus will be on creating
new classes.)
- An object of the
PercolationGUI
class provides a
graphical user interface, allowing the user to create a simulated
material, specify how porous it should be, add a percolating
substance to it, and run the simulation.
- The code that actually controls the simulation, in reaction to user actions
through the graphical user interface, is found in the
PercolationController
class and its
SlowPercolationController
subclass.
- The vertical slice of the porous material is represented by a
Grid
.
The Grid
class comes from the GridPkg library, so
you won't see it in your project or BlueJ class diagram.
- Objects in a grid must be
GridObject
objects, so the
classes you create will be subclasses of the GridObject
class. This class also comes from the GridPkg library, and so
does not appear in your project or BlueJ class diagram.
Throughout this lab you may want to have access to the
class documentation for the Grid
, GridObject
,
and Location
classes. This documentation can be found at
www.cs.kzoo.edu/GridPkg/GridPkgClassDocumentation/.
- One
GridObject
subclass is already provided for you:
SolidCell
. These objects
represent solid matter in the porous material.
For convenience,
this class actually inherits from the ColorBlock
class used by GridPlotter (which, in turn, inherits from
GridObject
).
- For now, ignore the
AbstractPercolator
class; you
will use it later.
- The graphical user interface also uses objects of several other classes
not shown in the diagram above,
including a
PercolationDataFileHandler
that allows the
user to read sample configurations for porous materials from files, or
save a configuration to a file.
Downloading and compiling a skeleton
version of the program:
- 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.)
- Copy the files you looked at in the previous Reading Code
exercise into the
PercolationCode folder:
-
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).
- 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:
-
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.)
- Which superclass constructor is being invoked by the two
calls to
super in the SolidCell
constructors?
- 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:
-
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 ,
-
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.
-
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.
-
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.
-
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.
|