CleverCode最近在使用qq邮箱日历提醒,这个日历提醒可以通过邮箱,微信等多个终端发送提醒消息,能够及时提醒用户需要做某件事了。CleverCode刚好也在看观察者模式,所以将他用设计模式的方式表现出来。
1 模式介绍
有时被称作发布/订阅模式,观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
2 模式组成
2.1 抽象主题(Subject):它把所有观察者对象的引用保存到一个聚集里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象。
2.2 具体主题(ConcreteSubject):将有关状态存入具体观察者对象;在具体主题内部状态改变时,给所有登记过的观察者发出通知。
2.3 抽象观察者(Observer):为所有的具体观察者定义一个接口,在得到主题通知时更新自己。
2.4 具体观察者(ConcreteObserver):实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题状态协调。
3 架构说明
4 项目实战
4.1 需要说明
设计一个日历提醒列表,每当有提醒事件的时候,可以通过qq终端,qq邮箱,微信给用户发送提醒事件。提醒事件到了,为主体对象的触发者。
4.2 设计架构图
4.3 php设计源码
<?php
//被观察者(目标)
interface Subject
{/*{{{*/
//添加观察者
public function attach(Observer $observer);
//移除观察者
public function detach(Observer $observer);
//通知观察者
public function notify(MsgDto $msg);
}/*}}}*/
//MsgDto(消息传输对象)
class MsgDto
{/*{{{*/
public $time;
public $info;
public static function create($time,$info)
{
$self = new self();
$self->time = $time;
$self->info = $info;
return $self;
}
}/*}}}*/
//被观察者(日历记事本)
class CalendarAlarm implements Subject
{/*{{{*/
private $_observers = array();
private $_isRun = false;
// 添加观察者
public function attach(Observer $observer)
{/*{{{*/
$this->_observers[] = $observer;
}/*}}}*/
//移除观察者
public function detach(Observer $observer)
{/*{{{*/
$key = array_search($observer,$this->_observers);
if(false !== $key)
{
unset($this->_observers[$key]);
}
}/*}}}*/
/**
* 通知观察者
*
* @param array $msg
* @access public
* @return void
*/
public function notify(MsgDto $msg)
{/*{{{*/
foreach($this->_observers as $observer)
{
$observer->update($msg);
}
}/*}}}*/
/**
* 设置是否允许
*
* @param mixed $bool
* @access public
* @return void
*/
public function setRun($bool)
{
if($bool)
{
$this->_isRun = true;
}
else
{
$this->_isRun = false;
}
}
/**
* 制造触发通知事件的条件
*
* @access public
* @return void
*/
public function process()
{
while($this->_isRun)
{
$time = time();
echo $time."\r\n";
//模拟时间到了,需要触发提醒事件
if($time % 6 == 0)
{
$msg = MsgDto::create($time,"你有新的提醒事项,编号:${time}");
$this->notify($msg);
}
sleep(1);
}
}
}/*}}}*/
//观察者接口
interface Observer
{/*{{{*/
public function update(MsgDto $msg);
}/*}}}*/
//qq终端观察者
class QQObserver implements Observer
{/*{{{*/
public function update(MsgDto $msg)
{
echo "【qq终端提醒您】:您有time:{$msg->time}事件,info:{$msg->info}\r\n";
}
}/*}}}*/
//qq邮箱终端观察者
class QQMailObserver implements Observer
{/*{{{*/
public function update(MsgDto $msg)
{
echo "【qq邮箱终端提醒您】:您有time:{$msg->time}事件,info:{$msg->info}\r\n";
}
}/*}}}*/
//微信终端观察者
class WeiXinObserver implements Observer
{/*{{{*/
public function update(MsgDto $msg)
{
echo "【微信终端提醒您】:您有time:{$msg->time}事件,info:{$msg->info}\r\n";
}
}/*}}}*/
function start()
{
$calendarAlarm = new CalendarAlarm();
$calendarAlarm->attach(new QQObserver());
$calendarAlarm->attach(new QQMailObserver());
$calendarAlarm->attach(new WeiXinObserver());
$calendarAlarm->setRun(true);
$calendarAlarm->process();
}
start();
?>
4.4 结果展示
技术交流
CleverCode是一名架构师,技术交流,咨询问题,请加CleverCode创建的qq群(架构师俱乐部):517133582。加群和腾讯,阿里,百度,新浪等公司的架构师交流。【架构师俱乐部】宗旨:帮助你成长为架构师!