zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    计算几何 判断点在直线的左右哪一侧
    图论 迪杰斯特拉dijkstra求最短路径
    图论 用prim法求最小生成树
    图论 邻接表广搜
    图论 用广搜搜邻接矩阵
    图论 邻接表建图+dfs
    图论 邻接矩阵建图+dfs遍历
    HDU 2141 二分查找
    二叉树知道前序和中序求后序,知道中序后序求中序
    二叉树的查找
  • 原文地址:https://www.cnblogs.com/winkey4986/p/6277501.html
Copyright © 2011-2022 走看看