定義一系列的演算法,把它們一個個封裝起來, 並且使它們可相互替換。本模式使得演算法的變化可獨立於使用它的客戶。
意圖
策略模式
定義一系列的演算法,把它們一個個封裝起來, 並且使它們可相互替換。本模式使得演算法可獨立於使用它的客戶而變化。
適用性
許多相關的類僅僅是行為有異。“策略”提供了一種用多個行為中的一個行為來配置一個類的方法。
需要使用一個演算法的不同變體。例如,你可能會定義一些反映不同的空間/時間權衡的演算法。當這些變體實現為一個演算法的類層次時,可以使用原則模式。
演算法使用客戶不應該知道的資料。可使用原則模式以避免暴露複雜的、與演算法相關的資料結構。
一個類定義了多種行為, 並且這些行為在這個類的操作中以多個條件陳述式的形式出現。將相關的條件分支移入它們各自的Strategy類中以代替這些條件陳述式
關於模式本身的概念,請參考網上其它文章
此處只討論在PHP實際開發過程中的應用
此模式將演算法與資料進行分離.
演算法:狹義演算法,對固定結構的輸入資料產生一個固定結構的輸出. 不同的演算法,輸入是相同的,輸出是不同但類似的,或輸出相同但實現過程不同.
資料:一個持有資料的對象/類定義.
應用此模式的情境:
1.多種不同類的資料對象, 持有相同結構的資料.
2.多種演算法對象,同一類或實現了同一介面
3.調用者先告訴資料對象將使用哪一個演算法 對象. 然後資料對象在商務邏輯中將使用指定的演算法 對象來對資料進行處理.
使用局限:
1.通常PHP不用於進行數學計算類的任務,這種任務通常由C/C++/Java來進行.
2.多種資料對象,多種演算法對象, 一般的PHP商務邏輯不會複雜到這種程度.
設想一個執行個體: 程式中有多個業務處理類, 我們要對業務處理過程記錄日誌, 現在有多種日誌方式可供選擇:文本/資料庫/網路應用.調用者可以自行選擇使用哪種日誌方式.
實現過程:
1.先定義一個日誌的父類/介面,然後建立三種具體的日誌實作類別
interface LogInterface {
public function log($data);
}
class LogFile implements LogInterface{
public function log($data){
//將資料寫入文字檔
}
}
class LogDB implements LogInterface{
public function log($data){
//將資料寫入資料庫
}
}
class LogNet implements LogInterface{
public function log($data){
//通過網路對資料進行日誌記錄
}
}
2.定義一個Trait (為所有業務類增加一些功能)
trait LogTrait{
//記錄具體的日誌對象
private $_log;
//調用者用來設定具體的日誌對象
public function setLog(LogInterface $log){
$this->_log=$log;
}
//業務類中使用的功能
//此方法可以定義為私人,如果沒有外部存取的話
//此方法的實現也可變更,資料可以使用參數方式傳遞
public function log(){
$this->_log->log($this->data);
}
}
3.所有的業務類(需要日誌功能的)
//此類可能已經繼承了父類
class ModelA {
use LogTrait;
//業務類中的某一段需要使用日誌的程式碼片段
public function process(){
//為日誌準備資料
$this->data=$data;
//記錄日誌,此代碼可在本類中多次出現,或被外部調用
$this->log();
}
}