我认为这个模式名称有先天的残疾!如果你确实理解了观察者模式你就能体会到了!
福尔摩斯不止一次对华生说:“我是在观察,而你是在看”。福尔摩斯那可真叫观察呀,对周围的事物简直观察到了极致了...
可观察者模式里的这群观察者可是不折不扣的懒汉!他们从不主动观察!他们只是等待被通知呢!所以我一直认为“订报模式”更能说明这个模式的意思,因为订报的人都很懒,他们就在家等着报纸送来。
所以我们就订报吧!一般订报的人都是想要了解最新的新闻,也就是说当报社出了新报纸的时候,订报的人想要尽快的得到新的报纸,报社的责任就是包新出的报纸“及时”地传给“订阅了报纸”的读者们。下面的例子就是订报:
报社肯定有一个清单,这个清单上有订阅报纸的人的信息,姓名,地址等信息;不管报社还是杂志社都得有这么一个清单啊,是不是应该抽象出一个“概念”来呀?这就是我们的主题啊,主题就是被观察的对象!再有,这个清单是动态的,可能随时有人订报,也可能有人退订,
还有不管你是订报纸,还是订杂志,都是观察者,至于你是不是个读者那得看你是不是实现了观察者接口,如果你给一个小狗类实现了观察者接口,那这个小狗就是一个观察者了,代码:
观察者接口,实现了这个接口的都叫观察者了,这就是本模式中所谓的观察者们:
package ob;
public interface Observer {
public void update(); //有什么新情况,我就得更新一下,(如果有新报纸出来,我就读一下呗)
}
下面是我们的主题接口了,这个主题应该有签到,签出和通知的功能——订报,取消订报和发新报纸的功能,哈哈:
package ob;
imp
ort java.util.ArrayList;
public class NewspaperOffice implements Subject {
private ArrayList<Observer> readers; //这个清单是报社的
private String newspaper = ""; //这个串就代表报纸
public NewspaperOffice(){
this.readers = new ArrayList<Observer>();
}
@Override
public void checkIn(Observer o) {
// TODO Auto-generated method stub
//有个读者订了报,我们就把这个读者放到清单里
readers.add(o);
}
@Override
public void checkOut(Observer o) {
// TODO Auto-generated method stub
//如果那个读者不想订报了,那就从清淡里除名!
int i = readers.indexOf(o);
if(i >= 0){
readers.remove(i);
}
}
@Override
public void notifyThem() {
// TODO Auto-generated method stub
//如果我有新的报纸出了,我就得更新一下我的订阅者手里的报纸
for(int i=0;i < readers.size();i++){
Observer reader = (Observer)readers.get(i);
reader.update();
}
}
//报社还得会生产新报纸
public void produceNewspaper(String newspaper){
this.newspaper = newspaper;
//每当生产完了新报纸,我就要通知我的订阅者们并让他们更新到最新的报纸
this.notifyThem();
}
public String getContent(){ //获得当前报纸的内容
return this.newspaper;
}
}
主题有了,可我们的观察者还没呢,我们有的只是一个接口,那我们就做一个读者吧:
读者是观察者,所以要实现观察者接口:
package ob;
public class Reader implements Observer {
private String name; //给读者起个名字
private NewspaperOffice newspaperOffice;//本读者感兴趣的报社
private String mynewspaper = ""; //用户手里的报纸
public Reader(String name ,NewspaperOffice newspaperOffice){ //读者不知道主题是什么东西,他只对报社有兴趣
this.name = name;
this.newspaperOffice = newspaperOffice;
}
@Override
public void update() {
this.setNewsPaper();//先更新一下手里的报纸
// 当读者收到新报纸的时候会有 什么反映呢?
System.out.println("Hi All,我是"+ this.name +" 我的新报纸来了哦!让我看看有什么内容:");
//看看有什么内容
System.out.println(this.mynewspaper);//打开手里的报纸,看看
}
public void setNewsPaper(){ //更新用户手里的报纸,这可是报社的责任呀
this.mynewspaper = newspaperOffice.getContent();
}
public void addMe(){ // 订报
newspaperOffice.checkIn(this);
}
public void removeMe(){ // 不订了
newspaperOffice.checkOut(this);
}
}
好啦,测试一下:
package ob;
public class ObTest {
public static void main(String[] args){
NewspaperOffice newspaperOffice = new NewspaperOffice();
//下面是我们众多的读者,订阅了我们的报纸
Reader Zhangsan = new Reader("张三",newspaperOffice);
Reader Lisi = new Reader("李四",newspaperOffice);
Reader Wangwu = new Reader("王五",newspaperOffice);
Zhangsan.addMe();
Lisi.addMe();
Wangwu.addMe();
newspaperOffice.produceNewspaper("火星出事啦!!");
//张三这个家伙,这个时候不想收到报纸了,因为人家开始上网看新闻啦!所以
Zhangsan.removeMe();
newspaperOffice.produceNewspaper("Hi");
}
}