zoukankan      html  css  js  c++  java
  • 设计模式之观察者模式—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);
        }
    }


  • 相关阅读:
    Ansible17:Playbook之tags
    Ansible15:文件管理模块及Jinja2过滤器
    Ansible16:Playbook高级用法
    Ansible14:Playbook条件语句
    Ansible13:Playbook循环语句
    etcd备份与恢复
    Kafka部署篇
    kafka原理篇
    Zookeeper的介绍与基本部署
    frp实现内网穿透
  • 原文地址:https://www.cnblogs.com/lukeguo/p/8824778.html
Copyright © 2011-2022 走看看