pubsub 设计模式

1 篇文章 0 订阅
1 篇文章 0 订阅

广播订阅模式介绍

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


广播订阅模式优点

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

广播订阅模式缺点

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

广播订阅模式总结

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


广播订阅模式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样例

<?php

date_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');



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值