设计模式之观察者模式—Observer

出版社+订阅者=观察者模式

  1. 报社的业务是出版报纸。

  2. 向某家报社订阅报纸,只要他们有新报纸出版,就会送给你。

  3. 当你不想再看报纸时,取消订阅。报社就不会再给你送报纸。

  4. 报社运营中,就会不断有人向他们订阅或取消报纸。 

报社:主题(Subject)

订阅者:观察者(Observer)

观察者模式

    定义了对象之间的一对多依赖,当主题对象改变状态时,它的所有观察者都会收到通知并自动更新。

 

报社+订阅者 案例:

//主题 是数据持有者
public interface Subject {
    public void addObserver(Observer o); //增加一个观察者
    public void deleteObserver(Observer o);//移除一个观察者
    public void notifyObservers();//通知所有观察者
}
 
//实现类代表一个观察者,观察者必须实现此接口,以便接受通知。
public interface Observer {
    /**
     * 当主题状态发生改变时,由主题调用此方法,通知观察者。
     * @param args 传递给观察者的更新数据。
     */
    void update(Object...args);
}
 
/**
 * 出版社
 */
public class Publisher implements Subject {
    private ArrayList<Observer> subscribers=new ArrayList<Observer>(); //很多订阅者(观察者)
    private String entertainment; //娱乐新闻
    private String sports; //体育新闻
    public void addObserver(Observer o) {
        this.subscribers.add(o);
    }
 
    public void deleteObserver(Observer o) {
        int i= subscribers.indexOf(o);
        if(i>=0) subscribers.remove(o);
    }
 
    public void notifyObservers() {
        for(Observer ob:subscribers){
            ob.update(entertainment,sports);
        }
    }
    //数据发生变化后,通知订阅者
    public void changed(){
        this.notifyObservers();
    }
    //更新新闻
    public void UpdateNews(String entertainment,String sports){
        this.entertainment=entertainment;
        this.sports=sports;
        this.changed();
    }
}
 
public class Subscriber01 implements Observer{
    public void update(Object... args) {
        //订阅者 收到新闻更新消息
        for(Object o:args){
            System.out.println("正在看新闻:"+o);
        }
    }
}
 
public class Test01 {
    @Test
    public void test(){
        Publisher publisher=new Publisher();
        //增加订阅者
        Subscriber01 sb01=new Subscriber01();
        Subscriber01 sb02=new Subscriber01();
        publisher.addObserver(sb01);
        publisher.addObserver(sb02);
        //报社更新新闻,自动通知所有订阅者
        String entertainment="20后,大话西游,重制后上映!!";
        String sports="马云加入了国家太极队";
        publisher.UpdateNews(entertainment, sports);
    }
}

JDK内置的观察者模式API

JDK的观察者模型中,主题对象被称为可观察对象Observable 

JDK的观察者模式API实现上面的例子

public class Publisher extends java.util.Observable{
    private String entertainment;
    private String sports;
    public void UpdateNews(String entertainment,String sports){
        this.entertainment=entertainment;
        this.sports=sports;
        this.setChanged(); //标记,可观察对象(主题对象)已经改变
        //拉模型通知所有订阅者
        //订阅者需要自己通过getter方法从主体对象中获取自己感兴趣的数据,
        this.notifyObservers();
    }
    public String getEntertainment() {
        return entertainment;
    }
    public String getSports() {
        return sports;
    }
}
 
public class Subscriber implements java.util.Observer {
 
    // 用拉模型 从主题对象只获取自己感兴趣的数据
    public void update(Observable o, Object arg) {
        if(o instanceof Publisher){
            Publisher pub=(Publisher)o;
            //订阅者只拉取自己感兴趣的娱乐新闻
            System.out.println(pub.getEntertainment());
        }
    }
}
 
public class Test01 {
    @Test
    public void test(){
        Publisher publisher=new Publisher();
        //增加订阅者
        Subscriber sb=new Subscriber();
        publisher.addObserver(sb);
        //报社更新新闻,自动通知所有订阅者
        String entertainment="20后,大话西游,重制后上映!!";
        String sports="马云加入了国家太极队";
        publisher.UpdateNews(entertainment, sports);
    }
}


posted @ 2014-07-24 00:00  忙碌的键盘  阅读(73)  评论(0编辑  收藏  举报