## Session 24

### Opening Exercise

After Session 23, our Ball hierarchy looks like this:

Add an ExpandingBall class to the Ball hierarchy. An ExpandingBall increases its radius by one pixel every time it moves. Use the delegation technique we learned for the DeceleratingBall class last time.

### The Solution

We add our new subclass in the same way as before: by delegating to another Ball.

Here is how we might use an ExpandingBall in the MultiBallWorld:

```    public MultiBallWorldFrame( Color ballColor )
{
super();

setSize ( FrameWidth, FrameHeight );
setTitle( "Ball World" );

ballArray = new BoundedBall[ BallArraySize ];
for (int i = 0; i < BallArraySize; i++)
{
ballArray[i] = new ExpandingBall(
new BoundedBall(
10, 15, 5, 3.0+i, 6.0-i, this)));
}
counter = 0;
}
```

We can also make an ExpandingBall that delegate to a ShadowBall:

```            ballArray[i] = new ExpandingBall(
10, 15, 5, 3.0+i, 6.0-i ) );
```

By delegating to a Ball, our ExpandingBall class works with any class in the Ball hierarchy. That, my friends, is polymorphism at work.

### Going All the Way

Just a second, though... A DeceleratingBall is a Ball, too. Shouldn't we be able to make an expanding, decelerating ball? Let's try it...

... we try it, with no success ...

What's going on here? Remember how our delegation technique works:

Then take a look at the move() methods in our DeceleratingBall and ExpandingBall classes:

```    public void move()           // IN EXPANDING BALL
{
workerBall.move();
workerBall.growBy( 1 );
}

public void move()           // IN DECELERATING BALL
{
workerBall.move();
}

```

ExpandingBall delegates not only a move() message, but also a growBy() message. A DeceleratingBall knows to delegate the move() message onto it worker ball, but not the growBy() message. But the worker ball is the ball being painted, so it needs to be the ball to grow by a pixel.

This points out one flaw in our design: DeceleratingBall and ExpandingBall need to delegate all of the messages they receive, even the ones sent via protected routes.

So, we add to DeceleratingBall protected delegation methods for all of the methods it inherits from Ball and Disk. We do the same to ExpandingBall

Now, we are able to execute this beautiful example of what the delegation technique can do for us:

```    for (int i = 0; i < numberOfBalls; i++)
{
int dx = (int) (20 * Math.random() );
int dy = (int) (10 * Math.random() );
ball[i] = new ExpandingBall(
new DeceleratingBall(
new BoundedBall( 100, 100, 10, dx, dy, this ) );
}
```

Amazing. Because one of our "delegators" is substitutable for instances of its superclass, we can delegate to another object that delegates! This, my friends, is polymorphism at work.

### Do You Recognize a Pattern?

We added flexibility and extensibility to our set of classes using the same ideas we have used over and over in previous programs: composition and inheritance.

The new twist in this solution is that DeceleratingBall and ExpandingBall use composition and inheritance at the same time, with the same class!

• Because DeceleratingBall delegates to another Ball, we can add deceleration behavior to any Ball, including an instance of a subclass.

• Because DeceleratingBall extends Ball, we can plug a DeceleratingBall into any Ball variable -- including the worker ball slot in another delegator.

This shows how substitutability can make programs easier to write.

This new twist is so common that it has its own name:

decorator

### Another Exercise

Our Ball hierarchy now looks like this:

But if we look at our code, we see that the DeceleratingBall class looks a lot like the ExpandingBall class.

We have violated the "Say it once and only once" rule!

Duplicated code was the motivation for the Decorator pattern in the first place, and using it has created more.

### A Simple Solution

This is a common problem when extending a class hierarchy. We add a new class that looks just like an existing one, with a small change. Duplicating code is a reasonable thing when we are trying to implement a new behavior -- it's often the easiest thing to do. But we don't want to have to maintain duplicated code over time.

Common problems tend to have common solutions. The solution to this problem isn't really new to us -- we factor the common behavior into a superclass:

Here is how to extract the superclass:

1. Create a DecoratedBall class that implements the behavior common to our two decorators.

```    public class DecoratedBall extends Ball
{
private Ball workerBall;

public DecoratedBall( Ball aBall ) { ... }

protected Ball worker()
{
return workerBall;
}

// ** DELEGATE ALL MESSAGES TO THE INSTANCE VARIABLE!
...
public void  move ()   { workerBall.move(); }
...
}
```

With class, programmers who want to implement a particular kind of Ball decorator do not have to implement any of the default behaviors, only the behaviors that they want to change.

2. Change each of the decorator classes to be a subclass of DecoratedBall.

For example:

```    public class DeceleratingBall extends DecoratedBall
{
public DeceleratingBall( Ball aBall )
{
super( aBall );
}

public void move()
{
super.move();
}
}
```

All of the DELEGATED METHODS are inherited!

### Evaluating the DecoratedBall Class

The DecoratedBall class offers the same benefits of the DeceleratingBall and ExpandingBall classes implemented using the Decorator pattern:

• Programmers who reuse the DecoratedBall class can write only the methods that they need for their applications. They can use this class to decorate any Ball because it has a Ball instance variable.

• Client code that uses a DecoratedBall, DeceleratingBall, and ExpandingBall can't tell them apart from plain old Balls. That is because a DecoratedBall is a Ball.

The new Ball hierarchy looks like this:

More generally, this is how we implement the Decorator pattern:

### The Effect of the Decorator Pattern

Our first DeceleratingBall from Session 23 (as a simple subclass):

```    public class DeceleratingBall extends Ball
{
public DeceleratingBall( int x, int y, int r, double dx, double dy )
{
super( x, y, r, dx, dy );
}

public void move()
{
super.move();
}
}
```

Our final DeceleratingBall after refactoring (as a subclass of DecoratedBall):

```    public class DeceleratingBall extends DecoratedBall
{
public DeceleratingBall( Ball aBall )
{
super( aBall );
}

public void move()
{
super.move();
}
}
```

Notice: our new DeceleratingBall class
looks just like the one we wrote before using the Decorator pattern!

A good design pattern will do that...

### Wrap Up

• Reading -- Study the code from today. Compile and run it. Modify and run it. Make it your own. Review these lecture notes.

• Homework -- Homework 8 is available and due on Friday.

### The Decorator Pattern

The Problem

We would like to add a behavior to a set of classes that share a common interface.

This problem is prevalent. It occurs in many domains and in many applications. Here are a few:

• We want to add features to individual balls in our ball games or to individual card piles in a set of card games.
• We want to add features to readers and writers in the Java library, such as buffering the input we read using a reader.
• We want to add windowing features to individual objects in a word processor or drawing program.

A Tempting Solution that Fails

Use inheritance to create a new class of objects that has the behavior.

Use instances of this class when you need the behavior, and use instances of the superclass otherwise.

This solution is impractical. Why?

We will need to create multiple subclasses and replicate the behavior in each.

What if we would like to add more behavior to the extended object? We have to make (many!) more subclasses!

The Solution

1. Create a "decorator" using composition to encapsulate an instance of the base class as an instance variable.
2. Implement the new behavior in the decorator. Delegate as much of the new behavior to the instance variable as possible.
3. Send all other messages recursively to the encapsulated object.
4. Use inheritance to make the decorator a subclass of the base class.

The idea of a decorator occurs in the real world, too, far away from computer programs. Consider how we "decorate" a picture:

Notice the similarities in those "class diagrams"...

### How Does the Decorator Pattern Work?

This is an example of using inheritance and composition together.

Inheritance creates substitutable classes. This allows a decorated object to be used in all the same places as the encapsulated object!

The superclass acts as an interface for all of its subclasses.

An application won't know -- or need to know -- what sort of MovableBall it is using. The ball responds to all the same messages.

Composition uses substitution to reuse the code in the base class, but in a way that is controlled by the decorator.

This allows us to add the same behavior to all of the classes in the hierarchy!

### When Should You Use a Decorator?

In a way, the decorator pattern allows us to add a new behavior to a single instance, rather than to the whole class.

This works well whenever the new behavior is orthogonal to the existing behaviors. A behavior is orthogonal if it is related to the existing behaviors but isn't like any one of them. When two behaviors can both occur, or neither occur, or occur one without the other, then those behaviors are orthogonal to one another.

For example, we cannot point to a particular place in the Ball hierarchy and say, "That's where deceleration belongs!" Deceleration 'cuts across' the Ball class hierarchy.

Using a decorator makes sense any time there are two varieties of some object, but the variations are not directly related. For example, balls that bounce off the walls and balls that decelerate.

Would implementing BoundedBall as a decorator be a good idea?

Eugene Wallingford ..... wallingf@cs.uni.edu ..... April 5, 2005