pubsub 设计模式

来源:互联网 发布:股票模拟交易系统源码 编辑:程序博客网 时间:2024/06/05 17:15

广播订阅模式介绍

打开收音机选择不同频率的节目时,就像是订阅某个电台的节目。广播节目的电台(广播者)并不需要知道谁在收听他们的电台节目,他们只需广播就行。同样对收听节目的人(订阅者)来说,也不关心谁广播的这些节目,只需要打开收音机并调频到这个频率,当有节目时就可以收到。


广播订阅模式优点

  • 解耦
  • 扩展
  • 清晰
  • 灵活
  • 测试

广播订阅模式缺点

  • 不保证消息是否投递成功
  • 不保证消息是否处理成功
  • 安全问题
  • 消息膨胀

广播订阅模式总结

可以来构建一个松耦合的系统,需要在系统安全性及扩展性上做更多复杂的设计及实践。


广播订阅模式javascript样例


var makePubSub = function () {var callbacks = {},        publish = function (){            //Turn arguments object into real array            var args = Array.prototype.slice.call(arguments, 0);                //Extract the event name which is the first entry            var ev = args.shift();            //Return if callbacks object doesn't contain     //any entry for event            var list, i, l;            if(!callbacks[ev]) { return this; }            list = callbacks[ev];                //Invoke the callbacks, passing in the rest of parameters            for (i=0, l=list.length; i<l; i=i+1){                list[i].apply(this, args);            }            return this;        },        subscribe = function (ev, callback){    //Check if ev is already registered    // If it isn't create an array entry for it            if(!callbacks[ev]){                callbacks[ev] = [];            }            callbacks[ev].push(callback);            return this;        };return {pub: publish, sub: subscribe};};test = makePubSub()test.sub('alert', function(){alert('hello');})test.pub('alert')


广播订阅模式php样例

<?phpdate_default_timezone_set("Asia/Shanghai");/** * 日志函数 * @param $message 日志内容 * @param string $tag 日志标题 * @return string  */function log_message($message = array(), $tag = 'debug'){    if (empty($message)) $message = "No Message";    $message = (array) $message;    $message = (count($message) == 1 && !is_array($message[0])) ? $message[0] : json_encode($message, JSON_UNESCAPED_UNICODE);    echo sprintf("%s - %s -> %s\n", strtoupper($tag), date("Y-m-d H:i:s"), $message);}interface PubSubInterface {    public function receive($topic, $message);}class PubSub {    private $_subcribes = [];    public function subscribe($topic = 'normal', $subscriber)     {        if (!isset($this->_subcribes[$topic]))         {            $this->_subcribes[$topic][] = [];        }         if (is_object($subscriber)) $this->_subcribes[$topic][] = $subscriber;    }        public function publish($topic = 'normal')     {        if (!empty($this->_subcribes) && isset($this->_subcribes[$topic]))         {            foreach ($this->_subcribes[$topic] as $object)             {                if (is_object($object))                 {                     call_user_func_array([$object, 'receive'], [$topic, $this->_getTopicData($topic)]);                }               }        }    }    public function _getTopicData($topic)     {        $config =  ['email' => '今天加班 :(', 'salary' => '今天发薪水 :)'];        return isset($config[$topic]) ? $config[$topic] : 'No Message';    }     public function getTopics() {        return array_keys($this->_subcribes);    }}class Work implements PubSubInterface {    public function receive($topic, $message)     {            log_message(' 新消息 '.$message, $topic);    }}class Family implements PubSubInterface {    public function receive($topic, $message)     {            log_message(' 新消息 '.$message, $topic);    }}/* usage */$work = new Work();$family = new Family();$ps = new PubSub();$ps->subscribe('email', $work);$ps->subscribe('salary', $work);$ps->subscribe('email', $family);$ps->publish('email');$ps->publish('salary');



原创粉丝点击