PHP設計模式之策略模式

介紹php

策略模式:定義了算法族,分別封裝起來,讓它們之間能夠互相替換,此模式讓算法的變化獨立於使用算法的客戶。算法

 

封裝:把行爲用接口封裝起來,咱們能夠把那些常常變化的部分,從當前的類中單獨取出來,用接口進行單獨的封裝。編程

互相替換:咱們封裝好了接口,經過指定不一樣的接口實現類進行算法的變化。this

 

思惟導圖spa

php策略模式-鴨子游戲

我來解釋下這個思惟導圖的過程:設計

1.Joe作了一套至關成功的模擬鴨子的遊戲。設計了一個超類Duck,而後讓各類鴨子繼承這個類。code

 

2.後來客戶提出要讓鴨子有飛的能力。因此Joe就在超類中加了個fly()方法,這樣下面的子類都有飛行的行爲。orm

   問題來了:1>原來Duck的子類中居然有橡皮鴨,橡皮鴨是不會飛的。——Joe用重載的方式,把橡皮鴨的fly()方法設置爲空.blog

                     2>覆蓋fly(),咱們看到了橡皮鴨的fly()裏,沒有任何代碼,若是之後咱們再添加別的不會飛的鴨子,那我麼還要這麼處理嗎?——那麼代碼重複了!繼承

 

3.上面2的方式咱們知道是有問題的,因此Joe想到把Duck作成接口,這樣每一個子類必須實現Duck裏的方法。這樣就保證每一個鴨子都能根據本身的須要添加行爲。

     問題來了:產品常常處於更新中,規格也在不斷的變化。致使每當有新鴨子的時候,Joe就要被迫檢查一遍子類是否覆蓋了fly()方法。——當你修改某個行爲的時候,你必須得往下追蹤並在每個定義此行爲的類中修改它。

 

4.綜合以上問題,Joe想到了把那些變化的部分從不變化的位置中抽出來。好比,咱們對fly()行爲,作了單獨的接口FlyBehavior。若是鴨子想要飛行功能的時候,咱們就讓鴨子實現FlyBehavior.

 

5.深造:咱們想讓鴨子有不一樣的飛行功能,讓它在運行時候作不一樣的飛行動做。讓鴨子類實現接口,只能讓鴨子有一種行爲。

因此Joe,想到用組合的防止,當鴨子須要其餘飛行功能要求的時候,咱們能夠用setBehavior()方式,指定性的飛行方式。

 

代碼

<?php

interface FlyBehavior{

    public function fly();

}

 

class FlyWithWings implements FlyBehavior{

    public function fly(){

        echo "Fly With Wings \n";

    }

}

 

class FlyWithNo implements FlyBehavior{

    public function fly(){

        echo "Fly With No Wings \n";

    }

}

class Duck{

    private $_flyBehavior;

    public function performFly(){

        $this->_flyBehavior->fly();

    }

 

    public function setFlyBehavior(FlyBehavior $behavior){

        $this->_flyBehavior = $behavior;

    }

}

 

class RubberDuck extends Duck{

}

// Test Case

$duck = new RubberDuck();

 

/*  想讓鴨子用翅膀飛行 */

$duck->setFlyBehavior(new FlyWithWings());

$duck->performFly();           

 

/*  想讓鴨子不用翅膀飛行 */

$duck->setFlyBehavior(new FlyWithNo());

$duck->performFly();

 

總結

總的來講,咱們在開發中的設計原則以下:

1.找出應用中可能須要變化之處,把它們獨立出來,不要和那些不須要變化的代碼混在一塊兒;

2.針對接口編程,不針對實現編程;

3.多用組合,少用繼承;

相關文章
相關標籤/搜索