观察者模式

我认为这个模式名称有先天的残疾!如果你确实理解了观察者模式你就能体会到了!

福尔摩斯不止一次对华生说:“我是在观察,而你是在看”。福尔摩斯那可真叫观察呀,对周围的事物简直观察到了极致了...

可观察者模式里的这群观察者可是不折不扣的懒汉!他们从不主动观察!他们只是等待被通知呢!所以我一直认为“订报模式”更能说明这个模式的意思,因为订报的人都很懒,他们就在家等着报纸送来。

所以我们就订报吧!一般订报的人都是想要了解最新的新闻,也就是说当报社出了新报纸的时候,订报的人想要尽快的得到新的报纸,报社的责任就是包新出的报纸“及时”地传给“订阅了报纸”的读者们。下面的例子就是订报:

报社肯定有一个清单,这个清单上有订阅报纸的人的信息,姓名,地址等信息;不管报社还是杂志社都得有这么一个清单啊,是不是应该抽象出一个“概念”来呀?这就是我们的主题啊,主题就是被观察的对象!再有,这个清单是动态的,可能随时有人订报,也可能有人退订,

还有不管你是订报纸,还是订杂志,都是观察者,至于你是不是个读者那得看你是不是实现了观察者接口,如果你给一个小狗类实现了观察者接口,那这个小狗就是一个观察者了,代码:

观察者接口,实现了这个接口的都叫观察者了,这就是本模式中所谓的观察者们:
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");
    }
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值