观察者模式
来源:互联网 发布:高达seed 知乎 编辑:程序博客网 时间:2024/06/06 10:38
我认为这个模式名称有先天的残疾!如果你确实理解了观察者模式你就能体会到了呀!
福尔摩斯老先生不止一次对华生说:“我是在观察,而你是在看”。人家福尔摩斯老先生那可真叫观察呀,对周围的事物简直观察到了及至了...
可观察者模式里的这群观察者可是不折不扣的懒汉!他们从不主动观察!他们只是等待被通知呢!所以我一直认为“订报模式”更能说明这个模式的意思,因为订报的人都很懒,他们就在家等着报纸送来。
所以我们就订报吧!一般订报的人都是想要了解最新的新闻,也就是说当报社出了新 报纸的时候,订报的人想要尽快的得到新的报纸,报社的责任就是包新出的报纸“及时”地传给“订阅了报纸”的读者们,你没订我的报纸,我给你,我傻啊?下面的例子就是订报呀:
报 社肯定有一个清单,这个清单上有订阅报纸的人的信息,姓名了,地址了什么的;我们再一“抽”(注意这里不是抽风是抽象),啊,不管报社还是杂志社都得有这 么一个清单啊,是不是应该抽象出一个“概念”来呀?是呀,这就是我们的主题啊,主题就是被观察的对象!再有啊,这个清单是动态的,可能随时有人订报,也可 能有人不订了,
还有不管你是读报啊,还是读杂志啊,都是观察者,至于你是不是个读者那得看你是不是实现了观察者接口,如果你给一个小狗类实现了观察者接口,那这个小狗就是一个观察者了,嘿嘿,废话少说,java上阵:
观察者接口,实现了这个接口的都叫观察者了,这就是本模式中所谓的观察者们(其实他们平时很懒的,嘿嘿):
package ob;
public interface Observer {
public void update(); //有什么新情况,我就得更新一下,(如果有新报纸出来,我就读一下呗)
}
下面是我们的主题接口了,这个主题应该有签到,签出和通知的功能——订报,取消订报和发新报纸的功能,哈哈:
package ob;
imp
public class NewspaperOffice implements Subject {
private ArrayList<Observer> readers; //这个清单是报社的,别人谁都不能看,保护读者隐私呀,得!所以得private
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("原来是虚惊一场呀!");
}
}
哈哈,只要一出新报纸,“订了报的”都会收到新报纸了...