## Session 23

### Opening Exercise

The physics department would like for us to write a simple "ball world" program that it can use to teach the idea of friction. In this program, we need for some Balls to decelerate. Every time one of these decelerating balls moves, its speed decreases by 1%.

Add a DeceleratingBall class to the Ball hierarchy for this purpose.

### A Simple Solution

After adding a new subclass, we have the following Ball hierarchy:

We create a DeceleratingBall just as we would a Ball:

```    DeceleratingBall b =
new DeceleratingBall( 10, 15, 5, 5.0, 10.0 );
```

### A New Wrinkle

After running the program, the physics department tells us that some decelerating balls need to bounce of the walls they hit, too. So we need a class of BoundedBalls that decelerate.

Fix the problem.

Here is another simple solution:

### How Good is Our Solution?

Our approach to this family of problems is straightforward: implement a decelerating version of any Ball class that needs a decelerating counterpart.

What are the strengths of this approach?

• It is simple.
• It is easy to implement right now.

What are the weaknesses of this approach?

• It is tedious.
• It repeats codes. The move() methods in the classes DeceleratingBall and DeceleratingBoundedBall are identical!

You may be asking yourself, "So what? It works."

### "So what? It works."

What happens if we need to change the deceleration factor, say, from 1% to 2%?

We must remember to make the change
in two different classes.

What happens if we need to add deceleration behavior to other Balls?

Yes, there are several.

More subclasses!

What happens if we need to add another kind of behavior to our ball classes, including the decelerating balls?

Even more subclasses!

Solutions that make future extensions to a program unbearable are probably not very good solutions at all...

### An Alternative Solution

BoundedBalls respond to the same set of messages as Balls.

So they are substitutable for one another.

Can we use this to our advantage?

Take a look at this solution.

Now, we create a DeceleratingBall by giving it a Ball to direct:

```    DeceleratingBall b = new DeceleratingBall(
new Ball( 10, 15, 5, 2.0, 5.0 ) );
```

How does a DeceleratingBall work now?

This approach takes advantage of substitutability. It creates an object that delegates most of its responsibilities to another object... without the client knowing the difference!

Our new ball hierarchy looks like this:

### How Good is Our New Solution?

What are the weaknesses of our new approach?

• It is more complex.

• Decelerating balls are a bit "bigger" and "slower" at run time.

• We have to write "delegation methods" once seems for all the public and protected methods in the inheritance chain, which is tedious.

What are the strengths of our new approach?

• It says it once and only once. The move() method that implements deceleration behavior occurs in one class. The deceleration factor lives in exactly one class.

• We can add deceleration behavior to any Ball with this same class!

• We can add deceleration behavior to any future subclass of Ball -- with no new code!!

• The tedium of writing the "delegation methods" once seems more palatable than repeatedly writing multiple subclasses for deceleration throughout the hierarchy. (And maybe we can find a way to minimize the tedium...)

We sometimes choose a more complex solution when it offers extensibility and flexibility as benefits.

### Wrap Up

• Reading -- Study the code from today. Compile and run it. Modify and run it. (Try having a DeceleratingBall delegate to another DeceleratingBall!) Make it your own. Study these lecture notes.

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

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