前言
今天我们开始一起聊一聊关于行为型设计模式-观察者模式。
内容概要:
1、什么是观察者模式
2、UML图
3、优点
4、怎么实现观察者模式+代码示例
一、什么是观察者模式
当一个对象状态发生改变时,依赖它的对象全部会受到通知,并自动更新。这里涉及四个角色,分别是:
1、抽象主题角色:首先它是一个接口,负责提供增加和删除观察者对象,其次,它保存了所有的对象引用,对观察者的引用。每一个主题可以有多个观察者。
2、具体主题:它是一个具体子类的实现,存储具体观察者对象的相关状态,当具体主题内部状态改变,给观察者通知。
3、抽象观察者:首先,他是一个接口,规定观察者必须实现的方法,并在观察主题发生改变时,将自己某些状态进行更新。
4、具体观察者:粗出具体主题对象和相关的状态,实现抽象观察者的接口,并实现update方法,使其自身状态与主题状态同步。
二、UML图
三、优点:
低耦合,非侵入式编码,更新更方便
观察者和主题之间的耦合度较小;
四、怎么实现观察者模式 代码示例
不废话,上PHP代码:
<?php
/************************************************************
** @Description:
** @Author: haodaquan
** @Date: 2017-03-17 12:36:31
** @Last Modified by: haodaquan
** @Last Modified time: 2017-03-21 09:47:36
*************************************************************/
# 抽象主题角色
interface Subject
{
#增加一个新的观察者对象
public function attach(Observer $observer);
#删除一个已注册过的观察者对象
public function detach(Observer $observer);
#通知所有注册过的观察者对象
public function notifyObservers();
}
#具体主题角色
class ConcreteSubject implements Subject
{
private $_observers;
public function __construct(){
$this->_observers = array();
}
#增加一个新的观察者对象
public function attach(Observer $observer){
return array_push($this->_observers, $observer);
}
#删除一个已注册过的观察者对象
public function detach(Observer $observer){
$index = array_search($observer, $this->_observers);
if ($index === FALSE || ! array_key_exists($index, $this->_observers)){
return FALSE;
}
unset($this->_observers[$index]);
return TRUE;
}
#通知所有注册过的观察者对象
public function notifyObservers(){
if (!is_array($this->_observers)){
return FALSE;
}
foreach ($this->_observers as $observer){
$observer->update();
}
return TRUE;
}
}
#抽象观察者角色
interface Observer
{
#更新方法
public function update();
}
#具体观察者
class ConcreteObserver implements Observer
{
#观察者的名称
private $_name;
public function __construct($name)
{
$this->_name = $name;
}
#更新方法
public function update()
{
echo 'Observer', $this->_name, ' has notified.<br />';
}
}
// 创建一个主题
$subject = new ConcreteSubject();
/* 添加第一个观察者 */
$observer1 = new ConcreteObserver('Martin');
$subject->attach($observer1);
echo '<br /> The First notify:<br />';
$subject->notifyObservers();
/* 添加第二个观察者 */
$observer2 = new ConcreteObserver('phppan');
$subject->attach($observer2);
echo '<br /> The Second notify:<br />';
$subject->notifyObservers();
/* 删除第一个观察者 */
$subject->detach($observer1);
echo '<br /> The Third notify:<br />';
$subject->notifyObservers();