一、什么是观察者模式
定义对象间的一种一对多的依赖关系。当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
有多个对象在关注着一个对象,如果这个对象的状态发生了改变,其它依赖(关注)它的对象就会收到通知,然后在接收到通知以后各个对象做出相应的动作。这里涉及到两个概念(观察者和被观察者(目标类)),被观察者只能有一个,而观察这个观察者的对象可以用多个。
观察者模式的结构:
Subject(被观察者或者说是目标):
attach(添加观察者)
detach(删除观察者)
notify(提醒观察者)–当被观察者的状态发生改变的时候调用这个方法
Observe(观察者):
update(更新方法)–当观察者状态发生改变调用提醒方法后观察者通过更新方法来做出不同响应(动作)。
二、天气预报项目中的观察者模式
2.1 Github上Demo链接
https://github.com/fuquanjava/system-core/tree/c81a00f32041463161a4f6248cf1c4acf4acf2de/design/src/main/java/design/%E8%A7%82%E5%AF%9F%E8%80%85%E6%A8%A1%E5%BC%8F/demo1
这个Demo描述的是,把老板是否外出的状态,通知正在看股票的职员,不然被抓到就要被扣工资啦~
2.2 观察者模式在此Demo中的实现原理
2.2.1 被观察者Subect
package design.观察者模式.demo1; import java.util.ArrayList; import java.util.List; /** * Hello-World 2015/8/9 11:16 * fuquanemail@gmail.com */
public class MM { private List<StockObserver> observerList = new ArrayList<>(); private String action; public void attch(StockObserver observer){ this.observerList.add(observer); } public void notifyObservers(){ for(StockObserver observer : observerList){ observer.update(); } } public void remove(StockObserver observer){ if(observerList.contains(observer)){ observerList.remove(observer); } } public void setAction(String action) { this.action = action; } public String getAction() { return action; } }
这里定义了一个MM类,也就是被观察者Subject老板;
类里面定义了:
a) attch(StockObserver observer) //添加观察者的方法。
b) remove(StockPObeserver observer) //移除观察者的方法。
c) notifyObserver() //一旦被观察者的状态发生变化,提醒观察者。
d) setAction(String action) getAction() //提供改变被观察者状态的接口。
2.2.2 观察者Obsever
package design.观察者模式.demo1; /** * Hello-World 2015/8/9 11:17 * fuquanemail@gmail.com */ public class StockObserver { private String name; private MM mm ; public StockObserver(String name , MM mm ){ this.name = name; this.mm = mm; } public void update(){ System.out.println(mm.getAction()); } }
这里定义了观察类StockObsever类
类里面定义了:
a) StockOberver(String name,MM mm) // StockerObsever类的构造器。
b) update() //定义了更新方法,当被观察者老板外出状态发生变化时,调用提醒方法,观察者看股票的职员通过更新方法来做出不同响应(动作)。
2.2.3 测试源码
package design.观察者模式.demo1; /** * Hello-World 2015/8/9 11:23 * fuquanemail@gmail.com */ public class Main { public static void main(String[] args) { MM mm = new MM(); StockObserver o1 = new StockObserver("tom", mm); StockObserver o2 = new StockObserver("jerry", mm); mm.attch(o1); mm.attch(o2); mm.setAction("老板来了.."); mm.notifyObservers(); mm.setAction("老板走了.."); mm.notifyObservers(); } }
这里定义两个观察者,职员tom和职员jerry,还定义了一个被观察者,老板mm,每当老板的外出情况发生变化时,调用被观察者的notifyObservers()方法通知观察者tom和jerry,观察者根据老板的外出状态做出不同的动作。
三、观察者的优缺点
优点:
1) 观察者模式实现了观察者和目标之间的抽象耦合;
2) 观察者模式实现了动态联动(一个对象的状态发生改变更新另一个对象);
3) 观察者模式支持广播通信。
缺点:
可能引起无谓的操作,可能观察者不需要全部update,引起资源浪费。