Dennis’s Weblog

Decorator Pattern

Posted on: October 6, 2008

Once you know the techniques of decorating, you’ll be able to give your (or someone else’s) objects new responsibilities without making any code changes to the underlying classes.

Design Principle: Classes should be open for extension, but closed for modification.

So the key point is find out the varies and then encapsulate them.

Q: How can I make every part of my design follow the Open-Closed Principle?

A: Usually, you can’t. Making OO design flexible and open to extension without the modification of existing code takes time and effort. In general, we don’t have the luxury of tying down every part of our designs (and it would probably be wastefu). Following the Open-Closed Principle usually introduces new levels of abstraction, which adds complexity to our code. You want to concentrate on those areas that are most likely to change in your designs and apply the principles there.

Be careful when choosing the areas of code that need to be extended; applying the Open-Closed Principle EVERYWHERE is wasteful, unnecessary, and can lead to complex, hard to understand code.

Inherience ——————code reuse!!!

The Decorator Pattern: attaches additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.

Okay, so we’re subclassing the abstract class Beverage in order to have the correct type,
not to inherit its behavior. The behavior comes in through the composition of decorators with
the base components as well as other decorators.

Yes, if we rely on inheritance, then our behavior can only be determined statically at
compile time. In other words, we get only whatever behavior the superclass gives us or that we
override. With composition, we can mix and match decorators any way we like… at runtime.

And as I understand it, we can implement new decorators at any time to add new
behavior. If we relied on inheritance, we’d have to go in and change existing code any time we
wanted new behavior.

I just have one more question. If all we need to inherit is the type of the component,
how come we didn’t use an interface instead of an abstract class for the Beverage class?
Sue: Well, remember, when we got this code, Starbuzz already had an abstract Beverage class.
Traditionally the Decorator Pattern does specify an abstract component, but in Java, obviously,
we could use an interface. But we always try to avoid altering existing code, so don’t “fix” it if
the abstract class will work just fine.

public class LowerCaseInputStream extends FilterInputStream {
public LowerCaseInputStream(InputStream in) {
super(in);
}
public int read() throws IOException {
int c = super.read();
return (c == -1 ? c : Character.toLowerCase((char)c));
}
public int read(byte[] b, int offset, int len) throws IOException {
int result = super.read(b, offset, len);
for (int i = offset; i < offset+result; i++) {
b[i] = (byte)Character.toLowerCase((char)b[i]);
}
return result;
}
}

//base on super class we create some new functions

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: