標籤:gety 組成 通過 nbsp 未來 英文 添加 get mat
設計模式之策略模式
學習:http://blog.csdn.net/hguisu/article/details/7558249/
1.什麼是策略模式?
在軟體開發中也常常遇到類似的情況,實現某一個功能有多種演算法或者策略,我們可以根據環境或者條件的不同選擇不同的演算法或者策略來完成該功能。策略模式把對象本身和運算規則區分開來,其功能非常強大,因為這個設計模式本身的核心思想就是物件導向編程的多態性的思想。
百度解釋:策略模式定義了一系列的演算法,並將每一個演算法封裝起來,而且使它們還可以相互替換。策略模式讓演算法獨立於使用它的客戶而獨立變化。
組成
—抽象策略角色: 策略類,通常由一個介面或者抽象類別實現。
—具體策略角色:封裝了相關的演算法和行為。
—環境角色:持有一個策略類的引用,最終給用戶端調用。
應用情境:
1、 多個類只區別在表現行為不同,可以使用Strategy模式,在運行時動態選擇具體要執行的行為。
2、 需要在不同情況下使用不同的策略(演算法),或者策略還可能在未來用其它方式來實現。
3、 對客戶隱藏具體策略(演算法)的實現細節,彼此完全獨立。
參考自李炎恢PHP教程第三季
情景假設:現在需要售賣課程,在調用課程類方式的時候可以計算出課程的總費用和當前參與課程的名稱,但是出現的情況是,課程是動態添加的。並且每個課程的單價的不一樣。也就是說每種課程的演算法是獨立於選課存在的。
用戶端檔案代碼:
<?php
//用戶端 使用者
//策略模式
require "Lession.class.php";
require "L.class.php";
require "English.class.php";
require "Math.class.php";
require "Sport.class.php";
//通過不同的參數來改變不同課程的行為,這種方式實現了類的切換 多態
$_lession = new Lession(5,new English());
echo $_lession->type().‘ ‘.$_lession->cost();//您購買的是英語課程 900
echo ‘<br/>‘;
$_lession = new Lession(5,new Math());
echo $_lession->type().‘ ‘.$_lession->cost();//您購買的是數學課程 1000
echo ‘<br/>‘;
$_lession = new Lession(5,new Sport());
echo $_lession->type().‘ ‘.$_lession->cost();//您購買的是體育課程 1250
require的幾個檔案分別代表
Lession.class.php策略類
L.class.php抽象介面,用於規範子類行為
English.class.php Math.class.phpSport.class.php三種課程
以英文課策略角色為例:
1.
$_lession = new Lession(5,new English());
當執行個體化策略類Lession類的時候,將選課人數5,和英語課類的對象傳遞給Lession類的建構函式,用於初始化Lession類
看lession類:
<?php
//策略模式
//課程類
class Lession{
//課程購買人數
private $_num;
//策略屬性,儲存具體策略角色對象的引用,例如ENGLISH或者MATH
private $_stragety;
//構造方法初始化
public function __construct($_num,$_stragety)
{
$this->_num = $_num;
$this->_stragety = $_stragety;
}
//攔截器
public function __get($key)
{
return $this->$key;
}
//返回具體策略角色課程所需要費用
public function cost(){
//$this->_stragety儲存了english對象的引用
//$this 表示lession類傳遞給english類
return $this->_stragety->cost($this);
}
//返回購買的課程
public function type(){
return $this->_stragety->type();
}
}
2.當執行個體化lession類的時候,傳入選課人數$_num(5),和一個具體策略角色類對象,分別賦值給私人屬性$_num和$_stragety;
3.當lession.php調用Lession.class.php中的cost()方法和type()方法的時候,傳回值的是:通過建構函式傳遞進來並賦值給私人屬性$_stragety的執行個體化English後的對象,並且用這個對象調用English類中cost方法,並將策略類傳遞給cost方法作為參數,通過English類中cost方法計算返回的值的值。
4.這個時候看English.class.php類 具體策略
<?php
class English extends L{
public function cost(Lession $_lession)
{
return 180*$_lession->_num;
}
public function type()
{
return ‘您購買的是英語課程‘;
}
}
English類中很簡單,就是cost和type兩個方法,但是看cost類中的參數,Lession $_lession表示限定參數只能是Lession這個類的引用,是Lession類中cost方法傳遞過來的,但是在Lesssion類中,$_num是私人屬性,無法擷取到,所以在Lession類中還有一個魔法方法__get(),當類外無法擷取相應的屬性,就會嘗試調用這個方法返回屬性值。
5.但是看到English類又繼承了L類,看一下L類
<?php
abstract class L{
abstract public function cost(Lession $_lession);
abstract public function type();
}
L類是一個抽象類別,包含兩個抽象方法,規定了繼承L類的子類必須實現這兩個方法,防止亂寫。
6.總體流程:用戶端執行個體化策略類,並且傳入執行個體化後的具體策略角色類的對象,策略類在其方法中使用具體策略角色類的對象調用屬於它的cost()方法,並且傳入本身,具體策略類繼承抽象類別用於規範自身的行為,並且接收策略類的參數,實現屬於自己的演算法。最終返回給用戶端。
也就是說,具體的策略角色可以根據自身的需要實現不同的演算法,但是在用戶端調用是統一策略類,只是傳入了不要的策略角色,實現了多態。
PHP設計模式之策略模式