假设你是一个Boss,对员工A,B,C发送消息,你希望一个一个的通知,还是发送一次通过,A,B,C员工都能自动收到相关的通知。
方式1,一个一个的通知:
abstract class Employee {
protected $_name = null;
public function __construct($name) {
$this->_name = $name;
}
public abstract function notify($msg);
}
class MyEmployee extends Employee {
public function notify($msg) {
echo "<br>Hi {$this->_name}, 你有新的消息 {$msg}<br>";
}
}
$aEmployee = new MyEmployee("A");
$bEmployee = new MyEmployee("B");
$cEmployee = new MyEmployee("C");
$employeeArr = [
$aEmployee,
$bEmployee,
$cEmployee,
];
foreach($employeeArr as $employee) {
$employee->notify("收钱啦");
}
方式2,一次通知,员工订阅通知:
class EmployObserver { //观察者
private $_employees = [];
public function addEmployee($name, Employee $employee) { //添加观察者
if ( isset($this->_employees[$name]) ) {
return false;
}
$this->_employees[$name] = $employee;
return true;
}
public function removeEmployee($name) { //移除观察者
if ( isset($this->_employees[$name]) ) {
unset($this->_employees[$name]);
}
return true;
}
public function notify($msg) { //通知
foreach($this->_employees as $employee) {
$employee->notify($msg);
}
}
}
$EmployObserver = new EmployObserver();
$EmployObserver->addEmployee('A', $aEmployee);
$EmployObserver->addEmployee('B', $bEmployee);
$EmployObserver->addEmployee('C', $cEmployee);
$EmployObserver->notify("到账了");
//现在c辞职, D 入职
$EmployObserver->removeEmployee('C');
$EmployObserver->addEmployee('D', new MyEmployee('d'));
$EmployObserver->notify("有人事变动");
方式一和方式二都能实现相同的效果,不同之处在,对通知对象增添,移除的灵活性。对于方式一,需要对employeeArr进行修改。而对于方式二,只需要 调用removeEmployee和addEmployee 这两个方法就能快速的进行移除和添加通知对象。
方式二的实现是今天的主角--观察者模式
观察者模式实现:一个目标可以有任意数目的依赖它的观察者。一旦目标的状态发生改变 , 所有的观察者都得到通知。