php設計模式(2)-- 觀察者模式 -- 用trait來改進的寫法

我的設計模式系列文章
[url=http://xieye.iteye.com/blog/2404077]php設計模式(1)-- 觀察者模式 -- spl標準寫法[/url]
[url=http://xieye.iteye.com/blog/2404082]php設計模式(2)-- 觀察者模式 -- 用trait來改進的寫法[/url]
[url=http://xieye.iteye.com/blog/2404140]php設計模式(3)-- 責任鏈(職責鏈)模式[/url]
[url=http://xieye.iteye.com/blog/2404169]php設計模式(4)-- 裝飾器模式[/url]


[size=x-large]分析[/size]

我們來重新思考一下前面的代碼,發現有一個不足,我僅僅是想實現觀察者,如果每個想實現觀察者的類,都寫那麼多代碼,不太好。
這裏我不使用繼承,原因:php只允許單繼承,如果爲了實現觀察者模式繼承的話,就不能繼承別的類了。

於是使用trait來解決,效果棒呆!對於前文的4個文件,修改User.php,再添加一個MySqlSubject.php,這樣的話,兩個觀察者類,和客戶端代碼無需任何修改,

最終,User類的代碼只有他自己的業務邏輯,無關的代碼被放到通用類MySqlSubject中,代碼十分清爽,且可以重用。

[size=x-large]代碼[/size]

MySplSubject.php

<?php
// 本類是可以通用的
trait MySplSubject {

/**
* @var SplObjectStorage
*/
private $observers = NULL;

private function create_observers(){
if ($this->observers==null) {
$this->observers = new SplObjectStorage();
}
}

public function attach(SplObserver $observer) {
$this->create_observers();
$this->observers->attach($observer);
}

public function detach(SplObserver $observer) {
$this->create_observers();
$this->observers->detach($observer);
}

public function notify() {
$this->create_observers();
foreach ($this->observers as $observer) {
$observer->update($this);
}
}

}


User.php

<?php

class User implements SplSubject {
// 由trait來實現接口
use MySplSubject;

private $email;
private $username;
private $mobile;
private $password;


public function __construct($email, $username, $mobile, $password) {
$this->email = $email;
$this->username = $username;
$this->mobile = $mobile;
$this->password = $password;

}

// 這是業務邏輯
public function changePassword($newPassword) {
echo __METHOD__, PHP_EOL;
$this->password = $newPassword;
$this->notify();
}

// 專門給監聽器的信息,也可以省略,然後對每個字段添加get方法
public function get_observer_info(){
return [
"email" => $this->email,
"mobile" => $this->mobile,
"username" => $this->username,
"password" =>$this->password,
];
}

}


效果展示同前文一樣:

User::changePassword
[email protected] 發送電子郵件成功。內容是:你好 張三你的新密碼是 654321,請妥善保管
向 手機13610002000 發送短信成功。短信內容是:你好 張三你的新密碼是 654321,請妥善保管
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章