- 创建型模式,共5种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式;
- 结构型模式,共7种:适配器模式、装饰器模式、代理模式、外观模式、桥连接模式、组合模式、享元模式;
- 行为型模式,共11种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
关于上面23中设计模式的大概介绍可以参考博客[2]。
观察者模型实例之烧开水
从一个烧开水的例子出发。现在我们有个热水器,我们用它来烧开水。在烧水的过程中,显示器和扬声器都一直监视水温。显示器将水温显示在显示屏上。另外,当水温超过90度时,扬声器开始发出警告,提示水快烧开。
Java实现
Java对观察者类的支持,主要体现在Observable类和Observer接口。
1. java.util.Observable类 = 被观察者
Observable类的主要方法:
public class Observable { void setChanged(); //设置被观察者的状态已经被改变 void clearChanged(); //清除被观察者状态的改变,此时再调用hasChanged()将返回false void addObserver(Observer observer); int countObservers(); void deleteObserver(Observer observer); void deleteObservers(); boolean hasChanged(); void notifyObservers(); void notifyObservers(Object arg); // 参数一般设定为被改变的属性 }
热水器类继承自Observerable类,作为一种具体的被监控对象:
public class Heater extends Observable { private int temperature; // get方法,返回水温 public int getTemperature(){ return temperature; } // set方法,设置水温 public void setTemperature(int temperature){ this.temperature = temperature; } // boilWater方法,烧水 public void boilWater(){ for(int i = 30; i <= 100; i++){ this.setTemperature(i); this.setChanged(); this.notifyObservers(this.getTemperature()); this.clearChanged(); } } }
2. java.util.Observer接口 = 观察者
Observer接口只有一个抽象方法需要被具体的观察者实现。
public interface Observer{ void update(Observable observable, Object arg); //这里的arg即Obserbale类里的notifyObservers(Object arg)传过来的参数 }
Note:当被观察者调用nofityObservers(*)方法时,会根据被观察者的hasChanged()方法来判断它的状态是否被改变。如果改变,则观察者调用update方法。否则不调用(即不更新)。
显示器和扬声器作为具体的热水器水温监视者,都需要实现Observer接口。对于显示器,它的update方法作用就是更新显示的水温。对扬声器,它的update方法则是在水温超过90度时发出警告。具体代码如下:
// 显示器 public class Displayer implements Observer { public void update(Observable observable, Object arg){ display((int)arg); } public void display(int temperature){ System.out.println("Current Temperature is: " + temperature + " degree."); } } // 扬声器 public class Alertor implements Observer { public void update(Observable observable, Object arg){ int temperature = (int) arg; if(temperature > 90){ alarm(); } } public void alarm(){ System.out.println("Warning: Temperature is over 90 degree!" ); } }
3. 测试类
public class TestObserver{ public static void main(String[] args){ // 生成设备 Heater heater = new Heater(); Displayer displayer = new Displayer(); Alertor alertor = new Alertor(); // 添加订阅 - 重点(!!!) heater.addObserver(display); heater.addObserver(alertor); // 烧水 heater.boilWater(); } }
4. 将上面的3个步骤统一起来,写到一个文件中如下:文件名TestObserver.java
import java.util.Observable; import java.util.Observer; public class TestObserver { public static void main(String[] args){ // 生成设备 Heater heater = new Heater(); Displayer displayer = new Displayer(); Alertor alertor = new Alertor(); // 添加订阅 heater.addObserver(displayer); heater.addObserver(alertor); // 烧水 heater.boilWater(); } } class Heater extends Observable { private int temperature; // get方法,返回水温 public int getTemperature(){ return temperature; } // set方法,设置水温 public void setTemperature(int temperature){ this.temperature = temperature; } // boilWater方法,烧水 public void boilWater(){ for(int i = 30; i <= 100; i++){ this.setTemperature(i); this.setChanged(); this.notifyObservers(this.getTemperature()); // 只需传入监视器感兴趣的变量 this.clearChanged(); } } } // 显示器 class Displayer implements Observer { public void update(Observable observable, Object arg){ display((int)arg); } public void display(int temperature){ System.out.println("Displayer: Current Temperature is: " + temperature + " degree."); } } // 扬声器 class Alertor implements Observer { public void update(Observable observable, Object arg){ int temperature = (int) arg; if(temperature > 90){ alarm(); } } public void alarm(){ System.out.println("Alertor: Warning: Temperature is over 90 degree!" ); } }
最后的输出结果为:
Displayer: Current Temperature is: 30 degree. Displayer: Current Temperature is: 31 degree. Displayer: Current Temperature is: 32 degree. ... Displayer: Current Temperature is: 90 degree. Displayer: Current Temperature is: 91 degree. Alertor: Warning: Temperature is over 90 degree! Displayer: Current Temperature is: 92 degree. Alertor: Warning: Temperature is over 90 degree! ... Displayer: Current Temperature is: 99 degree. Alertor: Warning: Temperature is over 90 degree! Displayer: Current Temperature is: 100 degree. Alertor: Warning: Temperature is over 90 degree!
总结
第一次写技术博客感觉比较费劲。原以为一个下午能把三种实现方法都写完的,结果只写完了Java部分。后续的Objective-C 和C#部分计划明天下午搞定。敬请期待。
欢迎交流和讨论^_^ ~ 如有任何问题,请发送到邮箱:fengfu0527@gmail.com
[1]. 《Design Patterns: Elements of Reusable Object-Oriented Software》
[2]. Java之美之设计模式,链接:http://bolg.csdn.net/zhangerqing/article/details/8194653
[3]. 《Java与模式》