Java Reference
In-Depth Information
// if registered, compare to other customers
if (isRegistered())
{
return (Firework) Rel8.advise(this);
}
// check spending over the last year
Calendar cal = Calendar.getInstance();
cal.add(Calendar.YEAR, -1);
if (spendingSince(cal.getTime()) > 1000)
{
return (Firework) LikeMyStuff.suggest(this);
}
// oh well!
return Firework.getRandom();
}
This code expects that if a promotion is on, it will be named in a
strategy.dat
file in a
config
directory that lies in the running program's class path. Barring this, the code will use
the
Rel8
engine if the customer is registered or the
LikeMyStuff
engine if the customer
has a known purchase record. If the customer is not registered and not a big purchaser, the
code selects and recommends a firework at random. The code works, and you might feel that
this is not the worst code you've ever seen. But we can make it better.
Refactoring to Strategy
The
getRecommended()
method presents several problems. First, it's long—long enough
that comments have to explain its various parts. Short methods are easy to understand, seldom
need explanation, and are usually preferable to long methods. In addition,
the
getRecommended()
method chooses a strategy and then executes it; these are two
different and separable functions. You can clean up this code by applying S
TRATEGY
. To do
so, you need to
•
Create an interface that defines the strategic operation
•
Implement the interface with classes that represent each strategy
•
Refactor the code to select and to use an instance of the right strategic class
Suppose that you create an
Advisor
interface and begin your refactoring by introducing
a
GroupAdvisor
class and an
ItemAdvisor
class. These classes can implement
a common
recommend()
operation by applying the off-the-shelf recommendation engines,
as Figure 23.2 shows.