【讀書筆記-重構與模式】 策略模式Strategy–封裝變化

來源:互聯網
上載者:User

Strategy模式:

定義一系列的演算法,把他們一個個封裝起來,並且是他們可以相互替換,Strategy模式使演算法可以獨立於使用它的使用者而變化。

具體來說,策略模式的關鍵特徵包括:

意圖:可以根據上下文,使用不同的商務規則或者演算法。問題:對所需演算法的選擇取決於發出請求的使用者或則要處理的資料。如果只有一些不會變化的演算法,就不需要該模式。解決方案:對演算法的選擇和演算法的實現相分離。允許根據上下文進行選擇。參與者與共同作業者:。。。。。。。。。效果:定義了一系列的演算法。可以不適用條件陳述式或者switch語句來調用。各個演算法擁有相同的介面。實現:讓使用演算法的類包含一個抽象類別,該抽象類別具有一個抽象方法指定如何調用演算法。每個衍生類別按照需要實現演算法。

根據物件導向的一些忠告:“考慮設計中什麼是可變的”,“對變化的概念進行封裝”,“優先使用對象組合聚集,而不是類繼承”。由此我們的作法是:

1.尋找變化,將他封裝在一個單獨的類中。2.將這個類包含在另一個類中。

《深入php物件導向模式和實踐》中給出的策略模式的例子:

假設我們已經穿撿了一個標記語言,現在測試需要一些問題,因此我們建立了Question類,並為其添加了mark( )方法。假設使用者回答問題時可以使用多種不同的標記方式,應該怎麼辦呢?

比如,現在要支援簡單的markLogic語言,直接匹配以及Regex匹配三種標記方式。可能首先想到的是使用子類來實現。

如果只是這一個方面的需求,這麼做還是能夠適應我們的需求的,但是如果我們被要求支援不同的類型==基於文本的問題和基於多媒體的問題,在一個繼承樹中穿件多個子類的方案會產生一些問題。

因此,“只要發現自己正在不斷地在幾成熟的各個分支中重複同一個演算法(無論是通過子類還是通過重複條件陳述式)請將這些演算法封裝成獨立的類型。”。

UML圖示:

實現:

abstract class Question{    protected $promp;    protected $marker;    public function __construct($promp,Marker $marker){        $this->marker = $marker;        $this->promp = $promp;    }    abstract  function mark($response);}

class TextQuestion extends Question{    public function mark($response){        echo  "[text-response:]".$response.PHP_EOL;        return $this->marker->mark($response);    }}

class AVQuestion  extends Question{    public function mark($response){        echo "[Av-response:]".$response.PHP_EOL;        return $this->marker->mark($response);    }}
class MarkLogicMarker extends Marker{    private $engine;    public function __construct( $test ){        parent::__construct($test);        $this->engine = new MarkPaser($test);    }    public function mark($response){        return $this->engine->evaluate( $response );    }}

class MatchMarker extends Marker{    public function mark($response){        return ($this->test == $response);    }}

class RegexMarker extends Marker{    public function mark($response){        return ( preg_match($this->test,$response) );    }}

class Config{    public static $configs = array(        'what is baby?'=>'yes',        'how can i love U?'=>'of course',        'may be tomorrow?'=>'yeah',        'should it be like this?'=>'maybe',        'the result is?'=>'1+1',    );}

class MarkParser{    private $test;    public function __construct($test){        $this->test = $test;    }    public function evaluate( $response ){        assert($response);        assert(in_array($response,array_keys(Config::$configs)));        return Config::$configs[$response];    }}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.