装饰者模式是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()); } }