装饰者模式是JDK中还有一个使用较多的设计模式,上一个是观察者模式(在Swing中大量使用),业内好的API设计无一离不开常见的设计模式,通常我们所说要阅读源代码,也是为了学习大牛们的设计思路。————题记
设计模式
观察者模式:定义了对象之间一对多的依赖,这样一来,当一个对象改变状态时。它的全部依赖者都会受到通知并自己主动更新。
装饰者模式:动态地将责任附加到对象上。
若要扩展功能。装饰者提供比继承者更有弹性的替代方案。
设计原则
(1)封装变化。
(2)多用组合,少用继承。
(3)针对接口编程,而不是针对实现编程。
(4)为了交互对象之间的松耦合设计努力。
对象之间的像话依赖降到了最低。有助于简历有弹性的OO系统,可以应对变化。
(5)类应该对扩展开发。对改动关闭。
目标是同意类easy扩展,在不改动现有代码的情况下,就能够搭配出新的行为。
要点
观察者模式定义了对象之间一对多的关系。
使用观察者模式时。能够从被观察者出推或拉数据。
观察者模式中。会改变的是主题的状态。以及观察者的数量和类型。用这个模式,你能够改变依赖于主题状态的对象,却不必改变主题。
继承属于扩展形式之中的一个,但不见得是达到弹性设计的最佳方式。
组合和托付可用于执行时动态加上新的行为。
装饰者能够在被装饰者的行为前面与或后面加上自己的行为。甚至代替,达到特有的目的。
装饰者会导致设计中出现很多小对象。假设过度使用。会让小程序变得复杂。
Java内置的观察者模式:Obverser接口与Obversable类。
缺点:
(1)Obversable是一个类,必须设计一个类继承他。假设想同一时候具有Obversable类和还有一个超类的行为,就会陷入两难。由于Java不支持多重继承。Obversable没有接口,无法建立自己的实现。
(2)Obversable将setChange()方法保护起来了。这样一来。除非继承,否则无法创建Obversable实例并组合到自己的对象中来。
真实世界的装饰者
java.io包内的类太多了。简直是排山倒海。
以下是一个典型的对象集合,用装饰者来将功能结合起来。以读取文件数据:
超类:InputStream
组件:FileInputStream、StringBufferInputStream、ByteArrayInputStream
抽象装饰者:FilterInputStream
详细装饰者:PushBackInputStream、BufferedInputStream、DataInputStream、LineNumberInputStream
观察者模式:
public interface Subject {
public void registerObserver(Observer o);
public void removeObserver(Observer o);
public void notifyObservers();
} public interface Observer {
public void update(float temp, float humidity, float pressure);
} public interface DispalyElement {
public void dispaly();
} public class WeatherData implements Subject {
private ArrayList observers;
private float temperature;
private float humidity;
private float pressure; public WeatherData() {
observers = new ArrayList();
} public void registerObserver(Observer o) {
observers.add(o);
} public void removeObserver(Observer o) {
int i = observers.indexOf(o);
if (i >= 0) {
observers.remove(i);
}
} //通知每个观察者
public void notifyObservers() {
for (int i = 0; i < observers.size(); i++) {
Observer observer = (Observer)observers.get(i);
observer.update(temperature, humidity, pressure);
}
} public void measurementsChanged() {
notifyObservers();
} public void setMeasurements(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
measurementsChanged();
} public float getTemperature() {
return temperature;
} public float getHumidity() {
return humidity;
} public float getPressure() {
return pressure;
}
} //測试代码
public class WeatherStation {
public static void main(String[] args) {
WeatherData weatherData = new WeatherData(); CurrentConditionsDisplay currentDisplay =
new CurrentConditionsDisplay(weatherData); weatherData.setMeasurements(80,65,30.4f);
}
}
装饰者模式:
//抽象类
public abstract class Beverage {
String description = "Unknown Beverage"; public String getDescription() {
return description;
} public abstract double cost();
} //CondimentDecorator必须能代替Beverage。所以将CondimentDecorator必须能代替Beverage。所以将扩展成Beverage类扩展成Beverage类
public abstract class CondimentDecorator extends Beverage {
//全部调料装饰者必须又一次实现getDescription()方法
public abstract String getDescription();
} //饮料代码扩展自Beverage
public class Espresso extends Beverage { public Espresso() {
description = "Espresso";
} public double cost() {
return 1.99;
}
} //装饰者
public class Soy extends CondimentDecorator {
Beverage beverage;//记录被装饰者 public Soy(Beverage beverage) {
this.beverage = beverage;
} public String getDescription() {
return beverage.getDescription() + ", Soy";
} public double cost() {
return .15 + beverage.cost();
}
} //測试代码
public class StarbuzzCoffee { public static void main(String args[]) {
Beverage beverage = new Espresso();
System.out.println(beverage.getDescription()
+ " $" + beverage.cost()); Beverage beverage2 = new DarkRoast();
beverage2 = new Mocha(beverage2);//层层装饰
beverage2 = new Mocha(beverage2);
beverage2 = new Whip(beverage2);
System.out.println(beverage2.getDescription()
+ " $" + beverage2.cost()); Beverage beverage3 = new HouseBlend();
beverage3 = new Soy(beverage3);
beverage3 = new Mocha(beverage3);
beverage3 = new Whip(beverage3);
System.out.println(beverage3.getDescription()
+ " $" + beverage3.cost());
}
}