JDK自带观察者的使用

被观察者

package observerForJDK;

import java.util.Observable;

/**
 * 新闻派发器,当有新的新闻时派发给所有的订阅读者(观察者)
 */
public class NewsDispatcher extends Observable {
    public void addNews(String news){
        this.setChanged();
        this.notifyObservers(news);
    }
}

观察者:

package observerForJDK;

import java.util.Observable;
import java.util.Observer;

/**
 * 读者(观察者)
 */
public class Reader implements Observer {

    private String name;

    public Reader(String name) {
        this.name = name;
    }

    public void update(Observable o, Object arg) {
        String news = (String)arg;
        System.out.println(name + "观察到 : " + news);
    }
}

测试:

package observerForJDK;

/**
 * 测试类
 */
public class app {
    public static void main(String[] args) {
        //体育新闻派发器
        NewsDispatcher sportNewsDispatcher = new NewsDispatcher();
        //it新闻派发器
        NewsDispatcher itNewsDispatcher = new NewsDispatcher();
        //观察者r1,r2,r3
        Reader r1 = new Reader("r1");
        Reader r2 = new Reader("r2");
        Reader r3 = new Reader("r3");
        //添加观察者
        sportNewsDispatcher.addObserver(r1);
        sportNewsDispatcher.addObserver(r2);
        itNewsDispatcher.addObserver(r3);
        //当有新的新闻的时候,通知观察者
        sportNewsDispatcher.addNews("中国队突破了历史获得了世界杯冠军!");
        itNewsDispatcher.addNews("ibm 收购 sun公司,java开始收费!");
    }
}

但这种写法有点问题,观察者需要手动一个一个add进去,太麻烦

改进下:被观察者不变

观察者:

package observerForJDK;

import java.util.Observable;
import java.util.Observer;

/**
 * 读者(观察者)
 */
public class Reader2 implements Observer {

    private String name;
    private Observable observable;

    public Reader2(Observable observable,String name) {
        this.observable = observable;
        this.observable.addObserver(this);
        this.name = name;
    }

    public void update(Observable o, Object arg) {
        String news = (String)arg;
        System.out.println(name + "观察到 : " + news);
    }
}

测试类:

package observerForJDK;

/**
 *
 */
public class app2 {
    public static void main(String[] args) {
        //体育新闻派发器
        NewsDispatcher sportNewsDispatcher = new NewsDispatcher();
        //it新闻派发器
        NewsDispatcher itNewsDispatcher = new NewsDispatcher();
        //观察者r1,r2,r3
        Reader2 r1 = new Reader2(sportNewsDispatcher,"r1");
        Reader2 r2 = new Reader2(sportNewsDispatcher,"r2");
        Reader2 r3 = new Reader2(itNewsDispatcher,"r3");
        //当有新的新闻的时候,通知观察者
        sportNewsDispatcher.addNews("中国队突破了历史获得了世界杯冠军!");
        itNewsDispatcher.addNews("ibm 收购 sun公司,java开始收费!");
    }
}

 更实用点的例子:小说网站作者和读者之间的订阅

//读者类,要实现观察者接口
public class Reader implements Observer{
    
    private String name;
    
    public Reader(String name) {
        super();
        this.name = name;
    }

    public String getName() {
        return name;
    }
    
    //读者可以关注某一位作者,关注则代表把自己加到作者的观察者列表里
    public void subscribe(String writerName){
        WriterManager.getInstance().getWriter(writerName).addObserver(this);
    }
    
    //读者可以取消关注某一位作者,取消关注则代表把自己从作者的观察者列表里删除
    public void unsubscribe(String writerName){
        WriterManager.getInstance().getWriter(writerName).deleteObserver(this);
    }
    
    //当关注的作者发表新小说时,会通知读者去看
    public void update(Observable o, Object obj) {
        if (o instanceof Writer) {
            Writer writer = (Writer) o;
            System.out.println(name+"知道" + writer.getName() + "发布了新书《" + writer.getLastNovel() + "》,非要去看!");
        }
    }
    
}

作者类:

//作者类,要继承自被观察者类
public class Writer extends Observable{
    
    private String name;//作者的名称
    
    private String lastNovel;//记录作者最新发布的小说

    public Writer(String name) {
        super();
        this.name = name;
        WriterManager.getInstance().add(this);
    }

    //作者发布新小说了,要通知所有关注自己的读者
    public void addNovel(String novel) {
        System.out.println(name + "发布了新书《" + novel + "》!");
        lastNovel = novel;
        setChanged();
        notifyObservers();
    }
    
    public String getLastNovel() {
        return lastNovel;
    }

    public String getName() {
        return name;
    }

}

然后我们还需要一个管理器帮我们管理这些作者。如下。

import java.util.HashMap;
import java.util.Map;

//管理器,保持一份独有的作者列表
public class WriterManager{
    
    private Map<String, Writer> writerMap = new HashMap<String, Writer>();

    //添加作者
    public void add(Writer writer){
        writerMap.put(writer.getName(), writer);
    }
    //根据作者姓名获取作者
    public Writer getWriter(String name){
        return writerMap.get(name);
    }
    
    //单例
    private WriterManager(){}
    
    public static WriterManager getInstance(){
        return WriterManagerInstance.instance;
    }
    private static class WriterManagerInstance{
        
        private static WriterManager instance = new WriterManager();
        
    }
}

好了,这下我们的观察者模式就做好了,这个简单的DEMO可以支持读者关注作者,当作者发布新书时,读者会观察到这个事情,会产生相应的动作。下面我们写个客户端调用一下。

//客户端调用
public class Client {

    public static void main(String[] args) {
        //假设四个读者,两个作者
        Reader r1 = new Reader("谢广坤");
        Reader r2 = new Reader("赵四");
        Reader r3 = new Reader("七哥");
        Reader r4 = new Reader("刘能");
        Writer w1 = new Writer("谢大脚");
        Writer w2 = new Writer("王小蒙");
        //四人关注了谢大脚
        r1.subscribe("谢大脚");
        r2.subscribe("谢大脚");
        r3.subscribe("谢大脚");
        r4.subscribe("谢大脚");
        //七哥和刘能还关注了王小蒙
        r3.subscribe("王小蒙");
        r4.subscribe("王小蒙");
        
        //作者发布新书就会通知关注的读者
        //谢大脚写了设计模式
        w1.addNovel("设计模式");
        //王小蒙写了JAVA编程思想
        w2.addNovel("JAVA编程思想");
        //谢广坤取消关注谢大脚
        r1.unsubscribe("谢大脚");
        //谢大脚再写书将不会通知谢广坤
        w1.addNovel("观察者模式");
    }
    
}

参考:http://blog.csdn.net/zuoxiaolong8810/article/details/9081079

posted @ 2017-01-12 11:36  人生如若初见  阅读(272)  评论(0编辑  收藏  举报