こんにちは、今日も”リンゴジュース”を飲みながら、PHPのデザインパターンの説明の続きをしようと思います。

前回は抽象的な話ばかりだったので、今回は具体例を上げながら、ソースコード書いて実装して説明したいと思います。

Observerパターン適用の例:

ショッピングサイトでよくある「ショッピングカート」cartの状態の変化を見てみましょう。

Subjectクラス即ち観測対象としてはショッピングカート自体で、観察者としてはオプション用観測クラスとOutPutSurveyクラスがあります。

 

観測対象のショッピングカートのShoppingCartクラスを書いてみます:
class ShoppingCart
classStart:

    public $goods;
    public $listeners;

    public function __construct()
    {
        $this->goods = array();
        $this->listeners = array();
    }

    public function add($gid)
    {
		if(isset($this->goods[$gid])):
			$this->goods[$gid] += $this->goods[$gid];
		else:
			1;
		endif;
        $this->inform();
    }

    public function remove($gid)
    {
		if(isset($this->goods[$gid])):
			$this->goods[$gid] -= $this->goods[$gid];
		else:
			0;
		endif;
        if ($this->goods[$gid] <= 0) {
            unset($this->goods[$gid]);
        }
        $this->inform();
    }

    public function get()
    {
        return $this->goods;
    }
	
    public function set($v)
    {
        return $this->goods[] = $v;
    }

    public function isExist($gid, $list)
    {
		if($list == $this->goods){
			return array_key_exists($gid, $this->goods);
		}
        return false;
    }

   //survey accuracy : 0.1
   //regict Observer method (survey accuracy)
   //$obj(surveyClass, $var)
   //surveyClassは下部のインタフェースより確認ください

    public function registSurvey($obj)
    {
        $this->survey[get_class($survey)] = $survey;
    }

   //survey accuracy : 0.1
   //to retire or delete Observer method
   //$obj(surveyClass, $var)
    public function delSurvey($obj)
    {
        unset($this->survey[get_class($survey)]);
    }

    //Give information to Observer
    public function inform()
    {
        foreach ($this->survey as $survey) {
            $survey->update($this);
        }
    }
endClass;

まず、クラスShoppingCartの中ではカートを操作するための必要な手段が用意されました:

  • add:::商品を追加
  • remove:::商品を削除
  • get:::指定した商品を取得
  • set:::商品を設定する(オプションが付いてる場合)
  • isExist:::商品のありなしの判定
  • registSurvey:::カートの状況の観測を行う
  • delSurvey:::カートの状況の観測しない
  • inform:::観測対象へのお知らせ

インタフェースsurveyClass

interface surveyClass {
    //ShoppingCartより商品の変動をDBへ反映
    public function update(ShoppingCart $sc);
}
endClass;
ここまで、観測対象のところまでは設計ずみですが、各オブジェクトを疎結合して協調するためのソースコードは今回は展開していないので、また次回にします。

 

理想的な実装する方法としてオプション(プレゼントか、クーポンか)の観測クラス(具体的なクライアントの希望によって)を作成します、もう一つはカートの内容を出力(OutPut)する用のOutPutSurveyクラスも必要だと思います。

 

また、Observerパターンを適用する一番重要なポイントとしては観察対象のクラスは観察者に公開する情報の範囲だと思います。
次回は上記Observerパターンの足りていないオプション用観測クラスとOutPutSurveyクラスでShoppingCartを実装しましょう~。

PHPによるデザインパターン