美文网首页
观察者模式

观察者模式

作者: 沐兮_d64c | 来源:发表于2018-09-30 11:44 被阅读0次

    1,概念

    1)java.util.Observable(被观察者)和java.util.Observer(观察者),分别代表观察者模式中的Subject和Observer。
    2)核心。 Observable/Subject中有包含一个观察者 Obsever的Vector列表,当Subject被观察者发生changed改变时,notifyObservers通知所有observer观察者。

    2,JDK观察者模式的支持

    1)被观察者

    public class Observable {
        private boolean changed = false;//是否发生了改变
        private Vector<Observer> obs;//(线程安全的)维护观察者列表
        
        //添加、注册观察者。线程安全
        public synchronized void addObserver(Observer o) {
            if (o == null)
                throw new NullPointerException();
            if (!obs.contains(o)) {
                obs.addElement(o);
            }
        }
    }
        //删除观察者
        public synchronized void deleteObserver(Observer o) {
            obs.removeElement(o);
        }
        
        //通知所有的观察者
        public void notifyObservers(Object arg) {
            //snapshot
            Object[] arrLocal;
            synchronized (this) {
                if (!changed)
                    return;
                arrLocal = obs.toArray();
                clearChanged();//Indicates that this object has no longer changed
            }
    
            for (int i = arrLocal.length-1; i>=0; i--)
                ((Observer)arrLocal[i]).update(this, arg);//call observer的update方法
        }
    
        protected synchronized void setChanged() {
            changed = true;
        }
        protected synchronized void clearChanged() {
            changed = false;
        }
    

    2)观察者Observer

    public interface Observer {
        //This method is called whenever the observed object is changed. 
        void update(Observable o, Object arg);
    }
    

    3,redis观察者模式(发布订阅功能)

    1)pub、sub结构

    image.png
    publisher:通过 PUBLISH 命令向订阅者发送信息的客户端
    subscriber:通过SUBSCRIBE 或者 PSUBSCRIBE 命令接收信息的客户端
    channel:解耦发布者(publisher)和订阅者(subscriber)之间关系的中介

    2)存储结构
    订阅频道

    struct redisServer { 
      // channlel - List<client>频道和订阅者client的列表
      dict *pubsub_channels; // Map channels to list of subscribed clients 
    };
    
    image.png
    SUBSCRIBE命令:将客户端添加到channel的订阅链表中。
    PSUBSCRIBE命令:订阅channel或者pattern,将客户端和订阅的模式添加到redisServer.pubsub_patterns 当中。
    redisServer.pubsub_channels是一个channel-list<client>的字典。
    redisServer.pubsub_patterns是一个链表。

    订阅模式

    struct redisServer { 
      list *pubsub_patterns; // A list of pubsub_patterns 
      };
    typedef struct pubsubPattern { 
      redisClient *client; 
      robj *pattern; 
      } pubsubPattern;
    
    image.png

    3)使用 PUBLISH 命令向订阅者发送消息。

    1)在 redisServer.pubsub_channels 字典中查找记录了订阅这个频道的所有客户端的链表,遍历这个链表,将消息发布给所有订阅者。
    2)遍历 redisServer.pubsub_patterns 链表,将链表中的模式和给定的频道进行匹配,如果匹配成功,那么将消息发布到相应模式的客户端当中。
    3)publish pbkey "pbkey1"
    subscribe pbkey
    psubscribe pbkey
    4)pubsub命令:redis2.8新增命令,客户端执行该命令,可以查看频道、模式的订阅信息。
    pubsub channels [pattern]
    pubsub numsub [channel-1]… :返回这些频道订阅者的数量。
    pubsub numpat [pattern-1]… :返回这些频道订阅者的数量。

    相关文章

      网友评论

          本文标题:观察者模式

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