这种模式 用的大为广泛,
比如一个新闻发布占,一个广播站,
基本只要是符合1:n 即一对多依赖关系的 ,都能使用这种模式。
也就是一个主题(Subject)以及多个Observer(观察者)。
考虑下面一个实例 就很容易理解了。
一个报纸,有个用户阅读。很显然,报社不需要知道用户在做什么。
他们只需要知道用户的门牌号(register),然后在每天发布新一期刊(releaseNews)的时候 把报纸送上门(通知用户,sendNotification)。
而observer在订阅报纸后,就只需等待报社送报纸上门阅读(update)了。
于是这个系统就可以这么设计:
首先Observer 只需要一个阅读的方法(update)。
Subject 需要 注册用户信息(register) , 以及通知用户(sendNotification)。
将他们设计成接口
public interface IObserver { ISubject subject = null;//对应的主题 void update(ISubject subject); }
import java.awt.List; import java.util.ArrayList; public interface ISubject { ArrayList<IObserver> observers = new ArrayList<IObserver>(); void register(IObserver o); void remove(IObserver o); void sendNotification(); }
public interface ISubject { ArrayList<IObserver> observers = new ArrayList<IObserver>(); void register(IObserver o); void remove(IObserver o); void sendNotification(); }
import java.util.Iterator; public class NewsPaperCenter implements ISubject{ String news = null; @Override public void register(IObserver o) { // TODO Auto-generated method stub observers.add(o); } @Override public void sendNotification() { // TODO Auto-generated method stub Iterator<IObserver> iterator= observers.iterator(); while (iterator.hasNext()) { iterator.next().update(this); } } @Override public void remove(IObserver o) { // TODO Auto-generated method stub observers.remove(o); } public void releaseNews(String _news){ news = _news; sendNotification(); } }
public class Reader implements IObserver{ int id; public Reader(int _id) { // TODO Auto-generated constructor stub id = _id; } @Override public void update(ISubject subject) { // TODO Auto-generated method stub NewsPaperCenter n = (NewsPaperCenter)subject; System.out.println(String.valueOf(id)+"#用户收到了新闻:"+ n.news); } }
public class main {
public static void main(String args[]) {
NewsPaperCenter n= new NewsPaperCenter();
// TODO Auto-generated constructor stub
for(int i = 1 ; i<=10 ; i++){
n.register(new Reader(i));
}
n.releaseNews("一个新的新闻");
}
}
运行结果为:
1#用户收到了新闻:一个新的新闻
2#用户收到了新闻:一个新的新闻
3#用户收到了新闻:一个新的新闻
4#用户收到了新闻:一个新的新闻
5#用户收到了新闻:一个新的新闻
6#用户收到了新闻:一个新的新闻
7#用户收到了新闻:一个新的新闻
8#用户收到了新闻:一个新的新闻
9#用户收到了新闻:一个新的新闻
10#用户收到了新闻:一个新的新闻
这样就很容易理解Observer的作用了
优点很明显:
观察者模式在被观察者和观察者之间建立一个抽象的耦合。被观察者角色所知道的只是一个具体现察者聚集,每一个具体现察者都符合一个抽象观察者的接口。被观察者并不认识任何一个具体观察者,它只知道它们都有一个共同的接口。由于被观察者和观察者没有紧密地耦合在一起,因此它们可以属于不同的抽象化层次。
观察者模式 在 observer和subject 之间通过接口 建立关系 ,subject 保留observer的地址(上述的Arraylist)。Observer不关心Subject,只在Subject通知Observer时,更新数据。 这样他们耦合很松。
当然缺点也有:
如果一个observer 依赖于另一个observer(这个observer 也是subject)..容易互相调用 死循环。
如果observer很多 遍历ArrayList<IObserver>会花费大量时间。