PHP設(shè)計模式——策略模式

策略模式定義了一系列的算法屁使,并將每一個算法封裝起來猎莲,而且使它們還可以相互替換流济。策略模式讓算法獨立于使用它的客戶而獨立變化锐锣,即封裝變化的算法。

適用場景:

1绳瘟、 多個類只區(qū)別在表現(xiàn)行為不同雕憔,可以使用Strategy模式,在運行時動態(tài)選擇具體要執(zhí)行的行為糖声。

2斤彼、 需要在不同情況下使用不同的策略(算法),或者策略還可能在未來用其它方式來實現(xiàn)蘸泻。

3琉苇、 對客戶隱藏具體策略(算法)的實現(xiàn)細節(jié),彼此完全獨立悦施。

4并扇、客戶端必須知道所有的策略類,并自行決定使用哪一個策略類抡诞,策略模式只適用于客戶端知道所有的算法或行為的情況穷蛹。

5、 策略模式造成很多的策略類昼汗,每個具體策略類都會產(chǎn)生一個新類肴熏。

有時候可以通過把依賴于環(huán)境的狀態(tài)保存到客戶端里面,可以使用享元模式來減少對象的數(shù)量顷窒。

UML類圖:


圖片.png

角色分析:

抽象策略角色(RotateItem):策略類蛙吏,通常由一個接口或者抽象類實現(xiàn)。

具體策略角色(ItemX):包裝了相關(guān)的算法和行為。

環(huán)境角色(ItemContext):持有一個策略類的引用鸦做,最終給客戶端調(diào)用璧疗。

具體代碼實現(xiàn):

<?php
/**
 * Created by PhpStorm.
 * User: Jiang
 * Date: 2015/5/16
 * Time: 21:46
 */
 
/**抽象策略角色
 * Interface RotateItem
 */
interface RotateItem
{
    function inertiaRotate();
    function unInertisRotate();
}
 
/**具體策略角色——X產(chǎn)品
 * Class XItem
 */
class XItem implements RotateItem
{
    function inertiaRotate()
    {
        echo "我是X產(chǎn)品,我慣性旋轉(zhuǎn)了馁龟。<br/>";
    }
 
    function unInertisRotate()
    {
        echo "我是X產(chǎn)品,我非慣性旋轉(zhuǎn)了漆魔。<br/>";
    }
}
 
/**具體策略角色——Y產(chǎn)品
 * Class YItem
 */
class YItem implements RotateItem
{
    function inertiaRotate()
    {
        echo "我是Y產(chǎn)品坷檩,我<span style='color: #ff0000;'>不能</span>慣性旋轉(zhuǎn)。<br/>";
    }
 
    function unInertisRotate()
    {
        echo "我是Y產(chǎn)品改抡,我非慣性旋轉(zhuǎn)了矢炼。<br/>";
    }
}
 
/**具體策略角色——XY產(chǎn)品
 * Class XYItem
 */
class XYItem implements RotateItem
{
    function inertiaRotate()
    {
        echo "我是XY產(chǎn)品,我慣性旋轉(zhuǎn)阿纤。<br/>";
    }
 
    function unInertisRotate()
    {
        echo "我是XY產(chǎn)品句灌,我非慣性旋轉(zhuǎn)了。<br/>";
    }
}
 
class contextStrategy
{
    private $item;
 
    function getItem($item_name)
    {
        try
        {
            $class=new ReflectionClass($item_name);
            $this->item=$class->newInstance();
        }
        catch(ReflectionException $e)
        {
            $this->item="";
        }
    }
 
    function inertiaRotate()
    {
        $this->item->inertiaRotate();
    }
 
    function unInertisRotate()
    {
        $this->item->unInertisRotate();
    }
}

測試代碼:

<?php
/**
 * Created by PhpStorm.
 * User: Jiang
 * Date: 2015/5/16
 * Time: 21:46
 */
 
header("Content-Type:text/html;charset=utf-8");
 
require_once "./Strategy/Strategy.php";
 
$strategy=new contextStrategy();
 
echo "<span style='color: #ff0000;'>X產(chǎn)品</span><hr/>";
$strategy->getItem('XItem');
$strategy->inertiaRotate();
$strategy->unInertisRotate();
 
echo "<span style='color: #ff0000;'>Y產(chǎn)品</span><hr/>";
$strategy->getItem('YItem');
$strategy->inertiaRotate();
$strategy->unInertisRotate();
 
echo "<span style='color: #ff0000;'>XY產(chǎn)品</span><hr/>";
$strategy->getItem('XYItem');
$strategy->inertiaRotate();
$strategy->unInertisRotate();

優(yōu)點:

1欠拾、 策略模式提供了管理相關(guān)的算法族的辦法胰锌。

策略類的等級結(jié)構(gòu)定義了一個算法或行為族。

恰當(dāng)使用繼承可以把公共的代碼轉(zhuǎn)移到父類里面藐窄,從而避免重復(fù)的代碼资昧。

2、 策略模式提供了可以替換繼承關(guān)系的辦法荆忍。

繼承可以處理多種算法或行為格带。

如果不是用策略模式,那么使用算法或行為的環(huán)境類就可能會有一些子類刹枉,每一個子類提供一個不同的算法或行為叽唱。但是,這樣一來算法或行為的使用者就和算法或行為本身混在一起微宝。決定使用哪一種算法或采取哪一種行為的邏輯就和算法或行為的邏輯混合在一起棺亭,從而不可能再獨立演化。繼承使得動態(tài)改變算法或行為變得不可能芥吟。

3侦铜、 使用策略模式可以避免使用多重條件轉(zhuǎn)移語句。

多重轉(zhuǎn)移語句不易維護钟鸵,它把采取哪一種算法或采取哪一種行為的邏輯與算法或行為的邏輯混合在一起钉稍,統(tǒng)統(tǒng)列在一個多重轉(zhuǎn)移語句里面,比使用繼承的辦法還要原始和落后棺耍。

缺點:

1贡未、客戶端必須知道所有的策略類,并自行決定使用哪一個策略類。

這就意味著客戶端必須理解這些算法的區(qū)別俊卤,以便適時選擇恰當(dāng)?shù)乃惴惸奂贰Q言之,策略模式只適用于客戶端知道所有的算法或行為的情況消恍。

2岂昭、 策略模式造成很多的策略類,每個具體策略類都會產(chǎn)生一個新類狠怨。

有時候可以通過把依賴于環(huán)境的狀態(tài)保存到客戶端里面约啊,而將策略類設(shè)計成可共享的,這樣策略類實例可以被不同客戶端使用佣赖。換言之恰矩,可以使用享元模式來減少對象的數(shù)量。

參考:
大話設(shè)計模式》憎蛤,作者程杰外傅。
https://blog.csdn.net/jhq0113/article/details/45771863

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市俩檬,隨后出現(xiàn)的幾起案子萎胰,更是在濱河造成了極大的恐慌,老刑警劉巖棚辽,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件奥洼,死亡現(xiàn)場離奇詭異,居然都是意外死亡晚胡,警方通過查閱死者的電腦和手機灵奖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來估盘,“玉大人瓷患,你說我怎么就攤上這事∏餐祝” “怎么了擅编?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長箫踩。 經(jīng)常有香客問我爱态,道長,這世上最難降的妖魔是什么境钟? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任锦担,我火速辦了婚禮,結(jié)果婚禮上慨削,老公的妹妹穿的比我還像新娘洞渔。我一直安慰自己套媚,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布磁椒。 她就那樣靜靜地躺著堤瘤,像睡著了一般。 火紅的嫁衣襯著肌膚如雪浆熔。 梳的紋絲不亂的頭發(fā)上本辐,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天,我揣著相機與錄音医增,去河邊找鬼师郑。 笑死,一個胖子當(dāng)著我的面吹牛调窍,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播张遭,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼邓萨,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了菊卷?” 一聲冷哼從身側(cè)響起缔恳,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎洁闰,沒想到半個月后歉甚,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡扑眉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年纸泄,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片腰素。...
    茶點故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡聘裁,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出弓千,到底是詐尸還是另有隱情衡便,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布洋访,位于F島的核電站镣陕,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏姻政。R本人自食惡果不足惜呆抑,卻給世界環(huán)境...
    茶點故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望汁展。 院中可真熱鬧理肺,春花似錦摄闸、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至乎完,卻和暖如春熏兄,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背树姨。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工摩桶, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人帽揪。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓硝清,卻偏偏與公主長得像,于是被迫代替她去往敵國和親转晰。 傳聞我的和親對象是個殘疾皇子芦拿,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,527評論 2 349

推薦閱讀更多精彩內(nèi)容