<< Chapter < Page | Chapter >> Page > |
Coming back to Ballworld, we see that the
updateState
method in
ABall
is an abstract algorithm to update the state of the ball. So, just as in the pizza example, we can represent this algorithm,
and just this algorithm , as an object. We can say that a ball
has an algorithm to update its state. Another wa of saying this is to say that the ball has a
strategy to update its state. We can represent this by using composition. Instead of having an abstract method to update the state, we model a ball as having a reference to an
IUpdateStrategy
object. The code for update thus becomes
public void update(Observable o, Object g)
{_strategy.updateState(this); // update this ball's state using the strategy
location.translate (velocity.x, velocity.y); // move the ballbounce(); // bounce the ball off the wall if necessary
paint((Graphics) g); // paint the ball onto the container}
The ball hands a reference to itself,
this
, to the strategy so that the strategy knows which ball to update. The variant updating behaviors are now represented by concrete implementations of the
IUpdateStrategy
interface.
(Note that the
Randomizer
class has been redesigned to eliminate its static methods. One new method has been added as well.)
There are a number of very important points to notice about this new formulation:
ABall
class now contains 100% concrete code and thus should not be abstract anymore.
ABall
has been renamed to simply
Ball
.getStrategy
and
setStrategy
) have been added.Ball
class is still 100% invariant code. CurveBall
,
StraightBall
, etc. subclasses are no longer needed as their variant behaviors have been moved to the
IUpdateStrategy
subclasses.
updateState
method has been moved from the
ABall
subclasses and embodied into their own classes.IUpdateStrategy
subclasses do not inherit anything from
Ball
, hence they do not contain any invariant code.this
), to a transient communication link (
host
).This new composition-based model of Ballworld is an example of the Strategy Design Pattern . The strategy design pattern allows us to isolate variant behaviors on a much finer level than simple inheritance models.
So far, all of our redesigning has resulted in a system that behaves exactly as it did when we started. But what one finds very often in developing systems is that in order to make two steps forward, one must first make one step backwards in order to fundmentally change the direction in which they are going. So, even though it looks like our system has not progressed because it still does exactly the same thing, we are indeed in a very different position, architecturally. By freeing the variant behaviors from the invariant ones, we have generated a tremendous amount of flexibility.
Notification Switch
Would you like to follow the 'Principles of object-oriented programming' conversation and receive update notifications?