裝飾模式核心內容:
- 觀察者模式又稱為發布訂閱模式,定義了物件間的一對多依賴關系,當一個物件狀態發生改變時,其相關依賴的其他物件都能接收到通知;
- 觀察者模式的核心在于目標(Subject)和觀察者(Observer)介面,目標有一個狀態屬性,觀察者“訂閱”這個目標,當目標的狀態屬性發生改變時,通知所有觀察者,
- 目標狀態改變只需核心業務邏輯并呼叫通知介面,無需關心具體的觀察者及其數量,降低物件之間的耦合度;
定義一個目標抽象類,提供系結&解綁觀察者的介面供客戶端使用,提供通知觀察者的介面供目標實作類使用:
abstract class Subject
{
protected $stateNow;
protected $observers = [];
public function attach(Observer $observer)
{
echo __CLASS__ . "系結觀察者:" . $observer->getClassName() . "\n\r";
array_push($this->observers, $observer);
}
public function detach(Observer $observer)
{
$pos = 0;
foreach ($this->observers as $viewer) {
if ($viewer == $observer) {
array_splice($this->observers, $pos, 1);
}
$pos++;
}
}
public function notify()
{
foreach ($this->observers as $viewer) {
echo __CLASS__ . "通知觀察者:" . $viewer->getClassName() . "\n\r";
$viewer->update($this);
}
}
}
定義一個目標實作類,實作狀態的變更業務:
class ConcreteSubject extends Subject
{
public function setState($state)
{
echo __CLASS__ . "修改狀態并呼叫 notify 方法\n\r";
$this->stateNow = $state;
$this->notify();
}
public function getState()
{
return $this->stateNow;
}
}
定義一個觀察者抽象類,規范接收通知的介面:
abstract class Observer
{
abstract public function update(Subject $subject);
abstract public function getClassName();
}
定義兩個觀察者實作類,實作接收通知的業務邏輯:
class ConcreteObserverEmail extends Observer
{
//維護一個指向具體目標物件的參考
private $currentState;
public function update(Subject $subject)
{
$this->currentState = $subject->getState();
echo $this->getClassName() . "收到了通知,內容為:" . $this->currentState . "\n\r";
}
public function getClassName() {
return __CLASS__;
}
}
class ConcreteObserverPhone extends Observer
{
//維護一個指向具體目標物件的參考
private $currentState;
public function update(Subject $subject)
{
$this->currentState = $subject->getState();
echo $this->getClassName() . "收到了通知,內容為:" . $this->currentState . "\n\r";
}
public function getClassName() {
return __CLASS__;
}
}
定義一個客戶端,給目標系結觀察者,查看效果:
class Client
{
public function main()
{
$sub = new ConcreteSubject();
$obEmail = new ConcreteObserverEmail();
$obPhone = new ConcreteObserverPhone();
$sub->attach($obEmail);
$sub->attach($obPhone);
$sub->setState('開啟');
}
}
(new Client())->main();
輸出結果:
Subject系結觀察者:ConcreteObserverEmail
Subject系結觀察者:ConcreteObserverPhone
ConcreteSubject修改狀態并呼叫 notify 方法
Subject通知觀察者:ConcreteObserverEmail
ConcreteObserverEmail收到了通知,內容為:開啟
Subject通知觀察者:ConcreteObserverPhone
ConcreteObserverPhone收到了通知,內容為:開啟
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/20934.html
標籤:PHP
上一篇:千圖圖片PHP決議
