美文网首页
观察者模式

观察者模式

作者: 四喜汤圆 | 来源:发表于2020-05-24 15:43 被阅读0次

    本文是对文中参考文献的学习笔记

    一、作用

    观察者模式描述了一对多的关系。当一个对象的状态改变时,它的所有观察者都可收到通知并进行相应更新。

    二、概念

    UML

    三、使用

    1.抽象出被观察者java.util.Observable

    实际使用时该抽象类/接口可省略

    手动敲了下java.util.Observable,它是一个 class 而不是接口,鸿洋如是说:"基本上书上都对于Java的如此设计抱有反面的态度,觉得Java内置的观察者模式,违法了面向接口编程这个原则,但是如果转念想一想,的确你拿一个主题在这写观察者模式(我们自己的实现),接口的思想很好,但是如果现在继续添加很多个主题,每个主题的ddObserver,removeObserver,notifyObservers代码基本都是相同的吧,接口是无法实现代码复用的,而且也没有办法使用组合的模式实现这三个方法的复用,所以我觉得这里把这三个方法在类中实现是合理的"

    /**
     * 重新调整了java.util.Observable的结构
     * @author yanglijin
     * @version v1.0
     * @since 2019-09-04
     */
    public class Observable {
        // 标志被观察者是否有变化
        private boolean changed = false;
    
        private Vector < Object > obs;
    
        // 构建一个有0个观察者的被观察者
        public Observable() {
            obs = new Vector < > ();
        }
    
        // 1,管理观察者
    
        /**
         * 添加观察者
         * @param   o   an observer to be added.
         * @throws NullPointerException    如果添加的o为null时,会抛出异常
         */
        public synchronized void addObserver(Observer o) {
            if (o == null) {
                throw new NullPointerException();
            }
            if (!obs.contains(o)) {
                obs.addElement(o);
            }
        }
    
        /**
         * 删除观察者
         * @param o:传入null 对该方法无影响
         */
        public synchronized void deleteObserver(Observer o) {
            obs.removeElement(o);
        }
    
        // 2,对象状态变化时通知观察值
        public void notifyObservers() {
            notifyObservers(null);
        }
    
        /**
         *
         * @param arg:通知被观察者时携带的参数
         */
        public void notifyObservers(Object arg) {
            Object[] arrLocal;
            synchronized(this) {
                if (!hasChange()) {
                    return;
                }
                arrLocal = obs.toArray();
                clearChanged();
            }
            for (int i = arrLocal.length - 1; i >= 0; i--) {
                ((Observer) arrLocal[i]).update(this, arg);
            }
    
        }
    
        public synchronized void setChanged() {
            changed = true;
        }
    
        public synchronized boolean hasChange() {
            return changed;
        }
    
        public synchronized void clearChanged() {
            changed = false;
        }
    
        public synchronized int countObservers() {
            return obs.size();
        }
    
    
    }
    

    2.实现具体的被观察者

    public class MyBookManager extends Observable {
        private List<Book> mBooks;
    
        // 构造一个空的图书集合
        public MyBookManager(){
            mBooks = new ArrayList<>();
        }
    
        public void addBook(Book newBook) {
            mBooks.add(newBook);
            // 通知观察者
            setChanged();
            notifyObservers(newBook);
        }
    
    }
    

    3.抽象观察者

    观察者具有的操作接口

    public interface Observer {
        /**
         *
         * @param var1:被观察者对象
         * @param var2:传递给观察者的参数
         */
        void update(Observable var1, Object var2);
    }
    

    4.具体观察者

    public class User implements Observer {
        private String userName;
    
        public User(String userName) {
            this.userName = userName;
        }
    
        @Override
        public void update(Observable observable, Object o) {
            if (o instanceof Book) {
                Book book = (Book) o;
                System.out.println(userName+"收到新书达到通知:"+book.toString());
            }
        }
    }
    

    5. 测试

    @Test
    public void testObserver() {
        MyBookManager bookManager = new MyBookManager();
    
        bookManager.addObserver(new User("小红"));
        bookManager.addObserver(new User("小明"));
    
        bookManager.addBook(new Book(1, "穆斯林的葬礼"));
    }
    
    小明收到新书达到通知:Book{id=1, name='穆斯林的葬礼'}
    小红收到新书达到通知:Book{id=1, name='穆斯林的葬礼'}
    

    参考文献

    观察者模式 : 一支穿云箭,千军万马来相见
    设计模式之观察者模式源码分析及实践
    观察者设计模式在Android开发中的应用

    相关文章

      网友评论

          本文标题:观察者模式

          本文链接:https://www.haomeiwen.com/subject/jjokyftx.html