首页 > 代码库 > 《Head First 设计模式》学习笔记——观察者模式 + 装饰者模式
《Head First 设计模式》学习笔记——观察者模式 + 装饰者模式
装饰者模式是JDK中另一个使用较多的设计模式,上一个是观察者模式(在Swing中大量使用),业内好的API设计无一离不开常见的设计模式,通常我们所说要阅读源码,也是为了学习大牛们的设计思路。————题记
设计模式
观察者模式:定义了对象之间一对多的依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会受到通知并自动更新。
装饰者模式:动态地将责任附加到对象上。若要扩展功能,装饰者提供比继承者更有弹性的替代方案。
设计原则
(1)封装变化。
(2)多用组合,少用继承。
(3)针对接口编程,而不是针对实现编程。
(4)为了交互对象之间的松耦合设计努力。
对象之间的像话依赖降到了最低,有助于简历有弹性的OO系统,能够应对变化。
(5)类应该对扩展开发,对修改关闭。
目标是允许类容易扩展,在不修改现有代码的情况下,就可以搭配出新的行为。
要点
观察者模式定义了对象之间一对多的关系。
使用观察者模式时,可以从被观察者出推或拉数据。
观察者模式中,会改变的是主题的状态,以及观察者的数量和类型。用这个模式,你可以改变依赖于主题状态的对象,却不必改变主题。
继承属于扩展形式之一,但不见得是达到弹性设计的最佳方式。
组合和委托可用于运行时动态加上新的行为。
装饰者可以在被装饰者的行为前面与或后面加上自己的行为,甚至取代,达到特有的目的。
装饰者会导致设计中出现许多小对象,如果过度使用,会让小程序变得复杂。
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 = http://www.mamicode.com/new WeatherData();>
装饰者模式:
//抽象类 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()); } }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。