設計模式對於每個人都非常有用
本片博文**自
觀察者模式為您提供了避免元件之間緊密耦合的另一種方法。該模式非常簡單:乙個物件通過新增乙個方法(該方法允許另乙個物件,即 觀察者 註冊自己)使本身變得可觀察。當可觀察的物件更改時,它會將訊息傳送到已註冊的觀察者。這些觀察者使用該資訊執行的操作與可觀察的物件無關。結果是物件可以相互對話,而不必了解原因。
乙個簡單示例是系統中的使用者列表。清單 4 中的**顯示乙個使用者列表,新增使用者時,它將傳送出一條訊息。新增使用者時,通過傳送訊息的日誌觀察者可以觀察此列表。
清單 4. observer.php
<?php
inte***ce
iobserver
inte***ce
iobservable
class
userlist
implements
iobservable
public
function
addobserver
($observer)}
class
userlistlogger
implements
iobserver
}$ul
=new
userlist()
;$ul
->
addobserver
(new
userlistlogger()
);$ul-
>
addcustomer
("jack");
?>
此**定義四個元素:兩個介面和兩個類。 iobservable 介面定義可以被觀察的物件, userlist 實現該介面,以便將本身註冊為可觀察。 iobserver 列表定義要通過怎樣的方法才能成為觀察者, userlistlogger 實現 iobserver 介面。圖 4 的 uml 中展示了這些元素。
圖 4. 可觀察的使用者列表和使用者列表事件日誌程式
如果在命令列中執行它,您將看到以下輸出:
% php observer.php
'jack' added to user list
%
測試**建立 userlist ,並將 userlistlogger 觀察者新增到其中。然後新增乙個消費者,並將這一更改通知 userlistlogger 。
認識到 userlist 不知道日誌程式將執行什麼操作很關鍵。可能存在乙個或多個執行其他操作的偵聽程式。例如,您可能有乙個向新使用者傳送訊息的觀察者,歡迎新使用者使用該系統。這種方法的價值在於 userlist 忽略所有依賴它的物件,它主要關注在列表更改時維護使用者列表並傳送訊息這一工作。
此模式不限於記憶體中的物件。它是在較大的應用程式中使用的資料庫驅動的訊息查詢系統的基礎。
命令鏈 模式以鬆散耦合主題為基礎,傳送訊息、命令和請求,或通過一組處理程式傳送任意內容。每個處理程式都會自行判斷自己能否處理請求。如果可以,該請求被處理,程序停止。您可以為系統新增或移除處理程式,而不影響其他處理程式。清單 5 顯示了此模式的乙個示例。
清單 5. chain.php
<?php
inte***ce
icommand
class
commandchain
public
function
runcommand
($name
,$args)}
}class
usercommand
implements
icommand
}class
mailcommand
implements
icommand
}$cc
=new
commandchain()
;$cc
->
addcommand
(new
usercommand()
);$cc-
>
addcommand
(new
mailcommand()
);$cc-
>
runcommand
('adduser'
,null);
$cc-
>
runcommand
('mail'
,null);
?>
此**定義維護 icommand 物件列表的 commandchain 類。兩個類都可以實現 icommand 介面 —— 乙個對郵件的請求作出響應,另乙個對新增使用者作出響應。 圖 5 給出了 uml。
圖 5. 命令鏈及其相關命令
如果您執行包含某些測試**的指令碼,則會得到以下輸出:
% php chain.php
usercommand handling 'adduser'
mailcommand handling 'mail'
%
**首先建立 commandchain 物件,並為它新增兩個命令物件的例項。然後執行兩個命令以檢視誰對這些命令作出了響應。如果命令的名稱匹配 usercommand 或 mailcommand ,則**失敗,不發生任何操作。
為處理請求而建立可擴充套件的架構時,命令鏈模式很有價值,使用它可以解決許多問題。
我們講述的最後乙個設計模式是 策略 模式。在此模式中,演算法是從複雜類提取的,因而可以方便地替換。例如,如果要更改搜尋引擎中排列頁的方法,則策略模式是乙個不錯的選擇。思考一下搜尋引擎的幾個部分 —— 一部分遍歷頁面,一部分對每頁排列,另一部分基於排列的結果排序。在複雜的示例中,這些部分都在同乙個類中。通過使用策略模式,您可將排列部分放入另乙個類中,以便更改頁排列的方式,而不影響搜尋引擎的其餘**。
作為乙個較簡單的示例,清單 6 顯示了乙個使用者列表類,它提供了乙個根據一組即插即用的策略查詢一組使用者的方法。
清單 6. strategy.php
<?php
inte***ce
istrategy
class
findafterstrategy
implements
istrategy
public
function
filter
($record)}
class
randomstrategy
implements
istrategy
}class
userlist}}
public
function
add(
$name
)public
function
find
($filter
)return
$recs;}
}$ul
=new
userlist
(array
("andy"
,"jack"
,"lori"
,"megan"))
;$f1
=$ul
->
find
(new
findafterstrategy
("j"))
;print_r
($f1);
$f2=
$ul-
>
find
(new
randomstrategy()
);print_r
($f2);
?>
此**的 uml 如圖 6 所示。
圖 6. 使用者列表和用於選擇使用者的策略
userlist 類是打包名稱陣列的乙個包裝器。它實現 find 方法,該方法利用幾個策略之一來選擇這些名稱的子集。這些策略由 istrategy 介面定義,該介面有兩個實現:乙個隨機選擇使用者,另乙個根據指定名稱選擇其後的所有名稱。執行測試**時,將得到以下輸出:
% php strategy.php
array([
0]=> jack
[1]=> lori
[2]=> megan
)array([
0]=> andy
[1]=> megan
)%
測試**為兩個策略執行同一使用者列表,並顯示結果。在第一種情況中,策略查詢排列在 j 後的任何名稱,所以您將得到 jack、lori 和 megan。第二個策略隨機選取名稱,每次會產生不同的結果。在這種情況下,結果為 andy 和 megan。
策略模式非常適合複雜資料管理系統或資料處理系統,二者在資料篩選、搜尋或處理的方式方面需要較高的靈活性。
結束語
PHP五種常用的設計模式 工廠模式
一直對設計模式有一種敬畏之心,每次想要看設計模式的時候就會想到erich gamma,richard helm,ralph johnson,john vlissides的黑皮 設計模式 基本都望而止步,要把那本書看完可不是一時半會的,而且在沒有專案經驗的情況下,個人感覺基本都是紙上談兵。今天在ibm...
PHP五種常見演算法
氣泡排序 created by phpstorm.user maguanya date 2018 1 9 time 下午1 38 氣泡排序 function bubble arr len count arr if len 1 for i 1 i len i return arr 先定義乙個陣列 ar...
php常見的設計模式
單例模式 單例模式就是只允許類被例項化一次,且通過介面由類本身建立。同時單例模式不允許clone和new final class mysocket public static function getinstance return self instance 禁止物件的轉殖 private func...