Dennis’s Weblog

Archive for the ‘Design Patterns’ Category

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

OO Principles :

  1. Encapsulate what varies.
  • vary1: The number of observers may change.  === use Composition and interface to encapsulate this change
  • vary2: The number of subject ‘s states may change. ===

          a. You can pull or push the data. === pull: use the get***() method to get the data.  push: the publisher send the data via function parameters: update(object ***);

          update(observerable o, object arg); (use such method you can utilize push and pull at the same time. o is the sender of message, and arg is the message. You can directly get the message from arg, or use the get***() methods of o the retrieve the information you want.

    2.Favor composition over inheritance.

       The Observer Pattern use composition to compose any number of observers with their subjects, These relationship aren’t set up by some kind of inheritance hierarchy, NO! They are set up at runtime by composition.

    3.Program to interfaces, not implementations.

    4.Strive for loosely coupled design between object that interact.

When two objects are loosely coupled, they have little knowledge about each other.

Then only one thing the subject know about the other is that it implements a certain interface.

We can add observers at any time.

We never need to modify the subject to add new types of observers.

we can reuse subjects and observers indepentently  of each other.

Changes to either subjects or observers will not affect the other.

Loosely coupled design allows us to design flexible OO systems that can handle changes because they minimize the interdependency between objects.

The subjects and observers connect upon interface, which use composition. In observers , they (has a)(dependency) subject, and subjects only know the knowledge about the interface, and call the method in the interface with aware of the implementation of the interface. 

Observer Pattern:

    Designs a one to many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

Java buildin Observer Pattern:

java.util.observerable          a class

java.util.observer                a interface

Make use of these two struct can help you. But there are also dark side!

ActionListener & EventHandler , they are all use observer pattern.

Point:

    Patterns just make well use of the OO principles!