zoukankan      html  css  js  c++  java
  • 设计模式之观察者模式

    观察者设计模式

      定义了对象之间一对多的关系。当一个对象的状态发生变化,它所有的依赖者会收到更新通知,并作出相应的变化。

    相关对象

      主题(Subject):主题是一个接口,接口规定了具体主题需要实现的方法,如添加、删除观察者以及通知观察者更新数据的方法;

      观察者(Observer):观察者是一个接口,该接口规定了具体观察者用来更细数据的方法;

      具体主题(ConcreteSubject):是实现主题接口的一个实例;

      具体观察者(ConcreteObserver):是实现观察者接口的一个实例;

      

    使用场景

      (1)聊天室程序:一个人发送一条消息给服务器,服务器会将该消息广播给聊天室内的其他人;

      (2)邮件订阅:多人订阅了《NBA》这个相关消息,当有新消息出现的时候,通过广播给所有订阅的人;

      (3)Servlet中,监听器的实现

    测试实例

      (1)观察者

    /**
     * Observer 抽象的观察者
     * @author yangkj
     */
    public interface Observer {
    
        void update(Subject subject);
    }

      (2)主题

    /**
     * 
     * <p>
     * Subject 主题
     * <p>
     * 
     * @author <a href="mailto:yangkj@corp.21cn.com">yangkj</a>
     * @version
     * @since 2016年9月26日
     */
    public abstract class Subject {
        /**
         * 观察者列表
         */
        private List<Observer> list = new ArrayList<>();
    
        /**
         * 添加观察者
         */
        public void registerOberver(Observer obs) {
            list.add(obs);
        }
    
        /**
         * 删除观察者
         */
        public void removerOberver(Observer obs) {
            list.remove(obs);
        }
    
        /**
         * 通知所有的观察者更新
         */
        public void noticeAllObserver() {
            for (Observer obs : list) {
                obs.update(this);
            }
        }
    }

      (3)具体主题

    /**
     * ConcreteSubject 具体的主题
     * @author yangkj*/
    public class ConcreteSubject extends Subject {
        
        private int status;
    
        public int getStatus() {
            return status;
        }
    
        public void setStatus(int status) {
            this.status = status;
            //主题对象值发生变化,通知所有观察者,进行状态值变化
            this.noticeAllObserver();
        }
    }

      (4)具体观察者

    /**
     * ConcreteObserver 具体的观察者
     * @author yangkj*/
    public class ConcreteObserver implements Observer {
    
        private int status;
    
        @Override
        public void update(Subject subject) {
    
            status = ((ConcreteSubject) subject).getStatus();
    
            System.out.println("广播通知,状态值发生变化为:" + status);
        }
    
        public int getStatus() {
            return status;
        }
        public void setStatus(int status) {
            this.status = status;
        }
    }

      (5)测试代码

    public class Client {
    
        public static void main(String[] args) {
            // 新建两个观察者
            Observer obsA = new ConcreteObserver();
            Observer obsB = new ConcreteObserver();
            // 定义目标对象
            ConcreteSubject sub = new ConcreteSubject();
            sub.registerOberver(obsA);
            sub.registerOberver(obsB);
            sub.setStatus(0);
            /**
             * 添加一个观察者
             */
            Observer obsC = new ConcreteObserver();
            sub.registerOberver(obsC);
            sub.setStatus(1);
            /**
             * 移除一个观察者
             */
            sub.removerOberver(obsB);
            sub.setStatus(10);
        }
    }

      测试结果


      

      当然我们自己实现的是有缺陷的,比如没有考虑并发同步的问题;在Java.util中已经为我们提供了相关的工具类,下面我们用这些工具类完成一个观察者设计模式。

    利用java.util.Observable和java.util.Observer实现观察者模式

      (1)观察者

    import java.util.Observable;
    import java.util.Observer;
    
    /**
     * ConcreteObserver 观察者
     * 
     * @author yangkj
     */
    public class ConcreteObserver implements Observer {
    
        private int status;
    
        @Override
        public void update(Observable o, Object arg) {
            status = ((ConcreteSubject) o).getStatus();
            System.out.println("广播通知,状态值变化为:" + status);
        }
    
        public int getStatus() {
            return status;
        }
    
        public void setStatus(int status) {
            this.status = status;
        }
    }

      (2)主题

    import java.util.Observable;
    /**
     * ConcreteObserver 具体的主题
     * 
     * @author yangkj
     */
    public class ConcreteSubject extends Observable{
    
        private int status;
    
        public int getStatus() {
            return status;
        }
        public void setStatus(int status) {
            this.status = status;
            //表示目标状态已经做了修改
            setChanged();
            //通知所有的观察者,并且将具体的状态值进行传递
            notifyObservers(status);
        }
    }

      (3)测试代码

    public class Client {
    
        public static void main(String[] args) {
            Observer obs1 = new ConcreteObserver();
            Observer obs2 = new ConcreteObserver();
            Observer obs3 = new ConcreteObserver();
            
            ConcreteSubject sub = new ConcreteSubject();
            sub.addObserver(obs1);
            sub.addObserver(obs2);
            sub.addObserver(obs3);
            sub.setStatus(20);
            
            System.out.println("广播者个数:"+sub.countObservers());
            
            sub.deleteObserver(obs3);
            System.out.println("广播者个数:"+sub.countObservers());
        }
    }

      测试结果

      

  • 相关阅读:
    109 01 Android 零基础入门 02 Java面向对象 03 综合案例(学生信息管理) 03 新增功能及实现 05 问题解析--通过一个方法完成学生和专业的双向关联
    108 01 Android 零基础入门 02 Java面向对象 03 综合案例(学生信息管理) 03 新增功能及实现 04 问题解析--数组未实例化造成的空指针异常
    107 01 Android 零基础入门 02 Java面向对象 03 综合案例(学生信息管理) 03 新增功能及实现 03 编写方法完成学生个数统计功能
    106 01 Android 零基础入门 02 Java面向对象 03 综合案例(学生信息管理) 03 新增功能及实现 02 新增属性完成学生信息存储
    105 01 Android 零基础入门 02 Java面向对象 03 综合案例(学生信息管理) 03 新增功能及实现 01 新增需求及分析
    session与cookie的区别和联系
    session和cookie的区别
    Web服务器主动推送技术
    webSocket的场景应用
    TCP、Http和Socket 优劣比较
  • 原文地址:https://www.cnblogs.com/parryyang/p/5909503.html
Copyright © 2011-2022 走看看