1. 现实场景
每当有最新一期的报纸出版时,送报员都会按照订阅者的名单,把最新的报纸按时送到订阅者手里。而且订阅者也可以随时退订或者订阅其他的报纸,这就是观察者在现实生活中的应用。
2. 需求场景
用户可以在电脑端、安卓端查看股票行情,当股票价格和买卖数量发生变化时,要通知这两个客户端。
一般思路:
1 2 3 4 5 6 7 8 9 10 11 12
| public class ComputerClient { public void updatePrice(String name) { System.out.println(name + "股票在电脑上的价格更新了"); }
public void updateCount(String name) { System.out.println(name + "股票在电脑上的买卖数量更新了"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12
| public class AndroidClient { public void updatePrice(String name) { System.out.println(name + "股票在安卓上的价格更新了"); }
public void updateCount(String name) { System.out.println(name + "股票在安卓上的买卖数量更新了"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public class Stock { private String stockName = "中信证券";
public void changeCount() { ComputerClient computerClient = new ComputerClient(); computerClient.updateCount(stockName); AndroidClient androidClient = new AndroidClient(); androidClient.updateCount(stockName); }
public void changePrice() { ComputerClient computerClient = new ComputerClient(); computerClient.updatePrice(stockName); AndroidClient androidClient = new AndroidClient(); androidClient.updatePrice(stockName); } }
|
1 2 3 4 5 6 7 8 9
| public class Client { public static void main(String[] args) { Stock stock = new Stock(); stock.changePrice(); stock.changeCount(); } }
|
上面的代码没什么问题,但是,如果要增加一个苹果客户端,就要修改Stock类的代码,增加对苹果客户端的支持。而且,苹果客户端要写很多重复代码。
后来又不想支持苹果客户端了,这时又要修改Stock类的代码。
一个苹果客户端还好,如果还有更多其他的客户端呢?
3. 解决办法
如果能够在股票类增加一个功能,可以动态、随意地添加或删除客户端,是不是就可以解决这个问题呢?要实现动态、随意地添加或删除客户端,就必须面向接口编程,即把各种客户端抽象处理,在股票类里针对抽象的客户端编程。
4. 总结
观察者模式就是定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知并自动更新。观察者模式主要由4个部分组成:抽象目标类、具体目标类、抽象观察者类、具体观察者类。
5. 源码分享
https://github.com/voidking/design-pattern-behavior.git
6. 参考文献
《易学设计模式》
《大话设计模式》
接口设计六大原则
软件设计六大设计原则讲解