Java Reference
In-Depth Information
As we know, code duplication is a sign of bad design and should be avoided. We deal with it by
refactoring our code.
Code 11.10
Two of the filter-
handling methods from
ImageViewer
private
void
makeLighter()
{
if
(currentImage !=
null
) {
currentImage.lighter();
frame.repaint();
showStatus(
"Applied: lighter"
);
}
else
{
showStatus(
"No image loaded."
);
}
}
private
void
threshold()
{
if
(currentImage !=
null
) {
currentImage.threshold();
frame.repaint();
showStatus(
"Applied: threshold"
);
}
else
{
showStatus(
"No image loaded."
);
}
}
In this case, we want to find a design that lets us add new filters without having to add a new
dispatch method for the filter every time.
To achieve what we want, we need to avoid hard-coding every filter-method name
(
lighter
,
threshold
, etc.) into our
ImageViewer
class. Instead, we shall use a col-
lection of filters and then write a single filter-invocation method that finds and invokes
the right filter. This will be similar in style to the introduction of an
act
method when
decoupling the simulator from individual actor types in the
foxes-and-rabbits
project in
Chapter 10.
In order to do this, filters must themselves become objects, rather than just method names. If we
want to store them in a common collection, then all filters will need a common superclass, which
we name
Filter
and give an
apply
method (Figure 11.11 shows the structure, Code 11.11
shows the source code).
Every filter will have an individual name, and its
apply
method will apply that particular
sort of filter to an image. Note that this is an abstract class, as the
apply
method has to
be abstract at this level, but the
getName
method can be fully implemented so it is not an
interface.
Search WWH ::
Custom Search