碎碎念:
在此分享的是我學習中的一些理解和總結,大家一起學習和共勉,希望對大家有所幫助;在大家看了以後,覺得我理解和總結有不到位或者不對的地方希望大家在留言區指出,我會及時修改,感謝!!!
前言:
這篇文章接續上一篇文章,上一篇主要分享的是單例模式和介面卡模式,如果有沒有看過第二篇文章的朋友,下面有連結(淺談設計模式(二))。該篇主要分享的設計模式是:觀察者模式和策略模式。分享的每個設計模式都會透過 3 個方面(定義、舉例說明、程式碼說明)進行講解和說明。
正文:
觀察者模式
1.定義:
定義物件間的一種一對多的依賴關係,當一個物件的狀態發生改變時,所有依賴於它的物件都得到通知並被自動更新,簡單來說該模式相當於源 - 監聽(Source-Listener)模式(即監聽器)、釋出 - 訂閱(Publish-Subscribe)模式
2.舉例說明:
大家看這個例子的時候,最好結合下面的程式碼說明一起更好理解.
有一個軍營(即RegListener類),我們要想成為士兵(即觀察者),首先需要去軍營裡面註冊成為士兵(即RegListener下的add()方法),註冊成功後我們就成為了真正計程車兵(即listener1),所有計程車兵要聽從將軍的命令進行戰鬥(即所有listener類要實現update()方法),這時敵軍來犯,將軍釋出命令(即我們呼叫notice()方法),所有士兵收到命令後就開始戰鬥(即所有的listener類執行update()方法)。
這樣的舉例不知道大家是否能接受,思考了半天,感覺還是好尬呀!
3.程式碼說明:
A. 註冊觀察者(監聽)的介面
interface Subject {
public function add(Observer $observer);//增加一個新的觀察者物件
public function del(Observer $observer);//刪除一個已註冊過的觀察者物件
public function notice();// 通知所有註冊過的觀察者物件
B. 具體實現註冊觀察者類(監聽事件)
/**
* 具體主題角色(實現觀察者註冊類)
*/
class RegListener implements Subject {
private $listen;
public function __construct() {
$this->listen = array();
}
//增加一個新的觀察者物件
public function add(classname $class_object) {
if(!in_array($class_object,$this->listen)){
$this->listen[classname] = $class_object;
}
}
// 刪除一個已註冊過的觀察者物件
public function del(classname $class_object) {
if(isset($this->listen[classname])){
unset($this->listen[classname]);
return true;
}
return TRUE;
}
//通知所有註冊過的觀察者物件(觸發觀察者)
public function notice() {
//判斷是否有註冊過觀察者
if (!is_array($this->listen)) {
return FALSE;
}
//觸發所有觀察者
foreach ($this->listen as $classname=>$class_object) {
$class_object->update($key,$val); //觀察者的操作(如:文章瀏覽+1,文章總數+1,積分+1)
}
return TRUE;
}
}
C. 觀察者的介面和操作方法(所有觀察者呼叫介面,統一實現同一個名稱的方法)
//觀察者操作方法介面
interface ListenMethod
{
function update($class_object); //觀察者方法【統一方法名】 ($class_object類例項化物件)
}
//觀察者1(文章瀏覽量+1)
class listener1 implements ListenMethod
{
public function update(classnam $class_object)
{
$class_object-> setCount(1); //setCount()可以重新定義成文章+1或其他文章瀏覽+1或其他邏輯操作
}
}
//觀察者2(積分量+10)
class listener2 implements ListenMethod
{
public function update(classnam $class_object)
{
$class_object-> setIntegral(10); //setIntegral()也是我們監聽成功後要執行的方法
}
}
D. 觀察者模式的呼叫
class Achieve
{
public function test()
{
$Listener = new RegListener(); //例項化觀察者角色介面,用於註冊觀察者
$Listener->add(new listener1()); //註冊文章瀏覽+1觀察者
$Listener->add(new listener2()); //註冊積分+1觀察者
$Listener->notice();//觸發監聽和觀察者方法:文章瀏覽量加1 積分量加10
}
}
策略模式
1.定義: 白話理解就是用相同的方法實現不同的功能
2.舉例說明:
常見的排序演算法有快速排序,氣泡排序,歸併排序,選擇排序等,它們實現的方法都是sort(),那麼問題來了,我們怎麼只透過sort()方法就可以呼叫所有的排序演算法呢。這時,我們引入一個類,幫助我們實現。
3.程式碼說明:
A.Strategy (抽象策略介面類)
//抽象策略介面
abstract class Strategy{
abstract function sort(); //具體策略類要實現的方法
}
B.ConcreteStrategy (具體策略類)
class StrategyA extends Strategy
{
public function sort()
{
echo "這個類是氣泡排序類 <br>";
}
}
class StrategyB extends Strategy
{
public function sort()
{
echo "這個類是快速排序類 <br>";
}
}
C.Context 類(如何實現策略類,即我們引入的類)
//實現具體策略類
class Context{
protected $strategy;
//建構函式的引數是一個具體策略類的物件
public function __construct(Strategy $strategy)
{
$this->strategy = $strategy;
}
public function request()
{
$this->strategy->sort(); //實現具體排序類方法
}
}
D. 實現策略類
//呼叫StrategyA氣泡排序類
$strategyA = new StrategyA();
$context = new Context($strategyA);
$context->request();
//呼叫StrategyB快速排序類
$strategyB = new StrategyB();
$context = new Context($strategyB);
$context->request();
上一篇分享:【淺談設計模式(二)】部落格:[淺談設計模式(二)] 讓你一分鐘讀懂設計模式
本作品採用《CC 協議》,轉載必須註明作者和本文連結