设计模式-观察者模式

不想当设计模式巨星的程序员不是好设计师。从本期开始我们对设计模式做一个系统性的总结。HeadFirst设计模式看了两遍。我尽量将书中的每个模式的重点提取出来,方便研读。

观察者模式在日常开发中经常用到-比如按钮的监听、网络返回数据状态的监听、文件下载的监听等,都可以用观察者模式来实现。那么观察模式到底是怎样定义的,其中有哪些注意点?我们通过一项例子再来认识观察者模式:

比如有这样一个情节--------订阅报纸:

1、报社提供的业务是出版报纸。

2、用户只要向报社订阅了报纸,报社在有新报纸出版时,就会将报纸送给用户。而且用户一定可以收到新的报纸。

3、当用户不想看报纸时,取消订阅,再有新报纸时,报社也不会向用户推送。

观察者模式就跟订阅报纸是一回事,只是名称不一样罢了。

图释:



定义观察者模式:定义一个对象和多个依赖。当一个对象改变时,他的所有依赖者都会收到通知,并自动更新。

观察者模式提供了一种这样的设计思想。对象和依赖者之间是松耦合。他们依然可以交互,但是不太清楚彼此的细节。松耦合的设计之所以能让我们建立有弹性的OO(面向对象)系统,能够应对变化,是因为他们之间相互依赖的降低。


结合具体代码做一个简单的讲解。

1、根据出版社(Press)和读者朋友(Reader)两种角色来设计观察者模式,根据上文定义,出版社需要为读者朋友(Reader)提供三种功能:注册监听、取消监听、通知更新。读者朋友需要的技能是Reading。中间还需要一个观察者接口Observer来链接他们的状态更新。所以需要设计这样三个接口:

出版社接口

public interface IPress{
    public void registerObserver(Observer o);//注册观察者
    public void removeObserver(Observer o);//删除观察者
    public void notifyObservers();//通知更新
}

阅读者接口

public interface IReader(){
    public void  reading();//阅读者只有一个阅读功能
}

观察者接口
public interface IObserver{
  public void updata(String date,String  content);
}

2、依据上面接口,结合实际需求,写出相应实现。

出版社

public class PressData implements IPress{

    private ArrarList observers;
    private String date;
    private String content;

    public PressData(){
        observers=new ArrarList<IObserver>();
    }
    @Override
    public void registerObserver((Observer o){
        observers.add(o);
    }
    @Override
    public void removeObserver(IObserver o){
        int i=observers.indexOf(o);
        if(i>=0){
            observers.remove(i);
        }
    }
    @Override
    public void notifyObservers(){
        for(int i=0;i<observers.size();i++){
            IObserver observer=(IObserver)observers.get(i);
            observer.updata(date,content);
        }
    }


    public void setNewsData(String date,String content){
        this.date=data;
        this.content=content;
        notifyObservers;
    }

}

阅读者

public class Reader implements IObserver,IReader{

    private String date;
    private String content;
    private PressData pressData;

    public Reader(PressData pressData){
        this.pressData=pressData;
        this.pressData.registerObserver(this);
    }
    @Override
    public void updata(date,content){
        this.date;
        this.content=content;
        reading(date,content);
    }
    @Override
    public void reading(){
        System.out.println("News----"+date+"----"+content);
    }

}

3、具体调用

public class ReadingStation(){
    public static void main(String[] args){    
        PressData pressData=new PressData();
        Reader reader=new Reader(pressData);
        pressData.setNewsData("20170220","观察者模式");
    }
}

这里定义的观察者模式可能跟我们已经用到的不太一样。或许你会觉得稍微复杂了一点,怎么会这么多类?。。。实际确实如此,这里写的稍微松耦合了一下。实际我们之前写的时候一个类就搞定了。那么根据书中介绍的,再次强调,我们要注重松耦合。当然只定义一个Oberver去掉注册和取消监听的方法,我们直接实现Oberver类,然后传入调用接口行了,这样的情况也是有的。但是上面的例子确实值得思考。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值