这种模式 用的大为广泛,
比如一个新闻发布占,一个广播站,
基本只要是符合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>会花费大量时间。