php面向對象設計模式 之 觀察者模式

最近在學php 的設計模式, 看到了觀察者模式,在此寫下一點理解:php

問題:
假如一個小販, 他把產品的價格提高了, 不一樣的消費者會對此產生不一樣的反應。通常的編程模式無非是獲取提高的價格,而後獲取全部的消費者,再循環每一個消費者, 不一樣的消費者根據價格漲幅作出決定,若是消費者的類型有限,於是進行的判斷也很少,這種無可厚非,但若是有更多的類型的消費者加入進來, 那這個代碼就變得臃腫且難以維護, 由於要不停的往裏面加入判斷代碼,這個時候其實就適用觀察者模式了編程

思路:
  觀察者模式分爲兩個角色, 觀察者(observer)和被觀察者(observables), 先在被觀察者註冊一系列的被觀察者, 在被觀察者發生變化的時候,通知觀察者,進而觀察者自動進行更新,這種一對多的關係就像你是一個小販(被觀察者),賣東西,有不少人(觀察者)在買你的東西,假如你要升價, 這個時候全部的消費者(觀察者)能夠決定繼續買,仍是不買,仍是其餘動做,做爲小販(被觀察者)的你只須要把價格增長,繼而通知一下,而不用去管其餘人(觀察者)的動做。設計模式

實現:this

//先定義一個被觀察者的接口,這個接口要實現註冊觀察者,刪除觀察者和通知的功能。
 interface Observables
 {
    public function attach(observer $ob);
    public function detach(observer $ob);
    public function notify();
 }

 class Saler implements Observables
 {
    protected $obs = array();       //把觀察者保存在這裏
    protected $range = 0;

    public function attach(Observer $ob)
    {
        $this->obs[] = $ob;
    }

    public function detach(Observer $ob)
    {
        foreach($this->obs as $o)
        {
            if($o != $ob)
                $this->obs[] = $o;
        }
    }

    public function notify()
    {
        foreach($this->obs as $o)
        {
            $o->doActor($this);
        }
    }

    public function increPrice($range)
    {
        $this->range = $range;
    }

    public function getAddRange()
    {
        return $this->range;
    }
 }


 //定義一個觀察者的接口,這個接口要有一個在被通知的時候都要實現的方法
 interface Observer
 {
    public function doActor(Observables $obv);
 }

//爲了容易閱讀,我在這裏增長了一層,定義了一個買家, 以後會有Poor和Rich兩種不一樣的類型繼承這個類,用以表示不一樣類型的買家 
 abstract class Buyer implements Observer
 {
 }

 class PoorBuyer extends Buyer
 {
     //PoorBurer的作法
    public function doActor(observables $obv)
    {
        if($obv->getAddRange() > 10)
            echo  '不買了.<br />';
        else
            echo '還行,買一點吧.<br />';
    }
 }

class RichBuyer extends Buyer
{
    //RichBuyer的作法
    public function doActor(observables $obv)
    {
        echo '你再漲我也不怕,咱不差錢.<br />';
    }
}


$saler = new Saler();  //小販(被觀察者)
$saler->attach(new PoorBuyer()); //註冊一個低收入的消費者(觀察者)
$saler->attach(new RichBuyer()); //註冊一個高收入的消費者(觀察者)
$saler->notify(); //通知

$saler->increPrice(2);  //漲價
$saler->notify();  //通知

若是再有新的類型買家,只要再添加一個買家類型,繼承buyer,讓買家(被觀察者)註冊便可,而不用再去修改任何原來買家和賣家的任何內容設計

相關文章
相關標籤/搜索