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

    一、观察者模式

    观察者模式又叫发布-订阅模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象的状态发生变化时会通知所有的观察者对象,使它们能够自动地更新自己。当一个对象的改变需要改变其他的对象的时候就可以用观察者模式。

    二、结构图

    Subject类是抽象的主题对象,也是抽象通知者,可以从Observer观察者对象引用的聚集里面添加或者删除;

    Observer类是抽象观察者,在得到主题的通知时更新自己。

    三、示例

    import java.util.ArrayList;
    import java.util.List;
    
    //抽象通知者
    abstract class Subject{
        List<Observer> observers=new ArrayList<>();
        //增加观察者
        protected void attach(Observer observer){
            observers.add(observer);
        }
        //移除观察者
        protected void detach(Observer observer){
            observers.remove(observer);
        }
        //进行通知
        protected void notifying(){
            for (Observer o :observers) {
                o.update();
            }
        }
    }
    //抽象观察者
    abstract class Observer{
        abstract void update();
    }
    
    //具体通知者,将有关状态存入具体观察者对象,
    // 在具体主题的内部状态改变时,给所有登记过的观察者发出通知。
    class ConcreteSubject extends Subject{
        private String subjectState;
        //具体被观察者状态
    
        public String getSubjectState() {
            return subjectState;
        }
    
        public void setSubjectState(String subjectState) {
            this.subjectState = subjectState;
        }
    }
    
    //具体观察者
    class ConcreteObserver extends Observer{
        private String name;
        private String observerState;
        private ConcreteSubject subject;
        
        public ConcreteObserver(ConcreteSubject subject,String name){
            this.subject=subject;
            this.name=name;
        }
        
        @Override
        void update() {
            observerState=subject.getSubjectState();
            System.out.println("观察者"+name+"的状态:"+observerState);
        }
    }
    
    
    public class ObserverPattern {
        public static void main(String[] args) {
            ConcreteSubject s=new ConcreteSubject();
            s.attach(new ConcreteObserver(s,"one"));
            s.attach(new ConcreteObserver(s,"two"));
            s.attach(new ConcreteObserver(s,"three"));
        
            s.setSubjectState("ABC");
            s.notifying();
        }
    }

    输出结果:

    四、观察者模式的不足

    可以从上面的梳理中发现一些问题,

    首先,抽象的观察者和抽象的通知者还是耦合的,那如果缺少通知者或者观察者的抽象类,那就无法完成工作了呀;

    另外,观察者可能不一定是是更新状态这些抽象类中统一的操作,可能还会进行一些其他的操作,

    这些是需要改进的问题。

    如果可以使客户端来决定谁通知谁,那就可以优化上面的问题,

    那么可以去掉抽象观察者类,将各个具体的观察者的更新操作设置不同的方法名,

    通知者也不在依赖抽象观察者,添加与删除观察者也没必要了,但是那有如何处理具体通知者对观察者的通知呢?

    在.NET中可以通过委托来处理,

    但是,java当中没有委托啊。

    五、委托

    委托?什么是委托?怎么委托呢?

    可以这样说,在之前,我们是以通知者的通知来调用观察者的相应的更新方法的,

    但是委托就相当于把通知者的方法倒挂于通知者身上,相当于把不同的方法委托给通知者来更新了,

    只要通知者更新,就会使观察者更新。

    java当中没有对委托进行封装,但是通过反射还是能够实现实现事件委托,

    可以参考:https://blog.csdn.net/yanshujun/article/details/6494447#commentBox

    菜甜二的学习笔记and总结啊。。。总会遇到挫折,可是还是要保持开阔的心态才能开心的学习啊,坚持吧。
  • 相关阅读:
    apache2 开源协议
    zend framework入门教程
    对open页的打开页面进行刷新
    mysql -- 视图
    MySQL ---存储过程和触发器
    mysql --存储过程 select ...into
    mysql -- 存储过程,游标,错误异常处理
    mysql --存储过程 退出
    mysql -- 存储过程 in out inout
    mysql -- 死锁
  • 原文地址:https://www.cnblogs.com/chen-ying/p/11258386.html
Copyright © 2011-2022 走看看