您好,登錄后才能下訂單哦!
這篇文章給大家介紹怎么在PHP項目中實現一個解釋器模式,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
一、interpreterContext 這個類就像一個容器 主要是用來存放和獲取需要進行比較的值和比較的結果的,例如上述代碼中的4, four,和比較結果 “true”或“false”,保存的形式是數組即類的屬性$expressionstore,代碼如下:
class InterpreterContext{ private $expressionstore = array(); //存放比較的值和結果 function replace(Expression $exp,$value){ // 設置值 $this->expressionstore[$exp->getKey()] = $value; } function lookup(Expression $exp){ //獲取值 return $this->expressionstore[$exp->getKey()]; } }
這個類就像一個工具,供其他類來使用(它和其他類不存在繼承、組合或聚合的關系)。
二、Expression 這是一個表達式的抽象類,定義了抽象方法interpret() 和方法getKey()
代碼如下:
abstract class Expression { private static $keycount = 0; //計數用的 private $key; //存放一個唯一值 //主要實現將前臺獲取到的數據存放到上述InterpreterContext類中的功能,看到下面的內容就會發(fā)現繼承他的類調用了InterpreterContext類的replace()方法 abstract function interpret (InterpreterContext $context); //獲取一個唯一值 function getKey(){ if(!isset($this->key)){ self::$keycount++; $this->key= self::$keycount; } return $this->key; } }
下面將要講到的類都將繼承這個類,并且他和OperatorExpression(操作符表達式抽象類)是一個組合的關系,也就是說OperatorExpression在初始化時可以包含所有繼承了Expression的子類(這也是本書一直在強調的要面向接口編程,這個Expression就是個接口,利用這個接口可以實現多態(tài),不知道自己裝B說的對不對,哈! 具體可以在看看原書的類圖)
三、LiteralExpression 文字表達式類,作用就是將一個字符串保存到InterpreterContext這個小容器里,保存成一個索引數組,例如保存開頭那二句自創(chuàng)代碼中的 4 或者 four
代碼如下:
class LiteralExpression extends Expression{ private $value; function __construct ($value){ //初始化時傳入要保存的值 $this->value= $value; } function interpret(InterpreterContext $context){ //調用InterpreterContext類的replace()將$value保存到InterpreterContext這個小容器里 $context->replace($this,$this->value); } }
四、VariableExpression 變量表達式類,和上面類的作用是一樣的只不過數據將被保存成關聯數組,關聯數組中的健是變量名,值呢就是變量的值,例如開頭二句中的變量"input" 和值 "4",
代碼如下:
class VariableExpression extends Expression{ private $name; //變量名 private $val; //變量值 function __construct ($name,$val=null){ $this->name = $name; $this->val = $val; } function interpret(InterpreterContext $context){ if(!is_null($this->val)){ $context->replace($this,$this->val); $this->val = null; } } function setValue($value){ //用于設置變量的值 $this->val = $value; } function getKey(){ //這個復寫了父類的getKey()方法,在小容器InterpreterContext的lookup()方法調用這個類的實例的getKey()方法時 它將返回一個字符串(即變量名)而不是數字索引 return $this->name; } }
五、OperatorExpression 操作符表達式抽象基類,此類繼承且組合了Expression抽象基類,實現的interpret()方法主要保存表達式的計算結果
代碼如下:
abstract class OperatorExpression extends Expression{ protected $l_op; //表達式左邊的值 protected $r_op; //表達式右邊的值 function __construct (Expression $l_op,Expression $r_op){ //初始化時可組合繼承了Expression類的子類實例 $this->l_op = $l_op; $this->r_op = $r_op; } function interpret(InterpreterContext $context){ //主要用于保存表達試的結果(保存到InterpreterContext 類的實例中) $this->l_op->interpret($context); //將Expression子類實例的值或計算結果保存到InterpreterContext 類的實例中 $this->r_op->interpret($context); $result_l = $context->lookup($this->l_op); //獲取上一步的值或計算結果 $result_r = $context->lookup($this->r_op); $this->doInterpret($context,$result_l,$result_r); //具體的比較運算由繼承的子類來實現 } protected abstract function doInterpret(InterpreterContext $context,$result_l,$result_r); }
六、EqualsExpression、BooleanOrExpression、BooleanAndExpression,分別為繼承了OperatorExpression 抽象基類的相等表達式、或表達式、與表達式只有一個方法doInterpret()內部調用了InterpreterContext類的replace()方法將表達式的計算結果保存到InterpreterContext類的實例中
代碼如下:
//相等表達式 class EqualsExpression extends OperatorExpression { protected function doInterpret(InterpreterContext $context,$result_l,$result_r){ $context->replace($this,$result_l == $result_r); } } //或表達式 class BooleanOrExpression extends OperatorExpression{ protected function doInterpret(InterpreterContext $context,$result_l,$result_r){ $context->replace($this,$result_l || $result_r); } } //與表達式 class BooleanAndExpression extends OperatorExpression{ protected function doInterpret(InterpreterContext $context,$result_l,$result_r){ $context->replace($this,$result_l && $result_r); } }
到此為止此模式相關的類就介紹完畢,上述代碼都是進過測試的,可直接復制粘貼運行來查看結果,現在我們就來看看客戶端代碼:
客戶端代碼一:
$context = new InterpreterContext(); $statement = new BooleanOrExpression ( //可嘗試將此操作符表達式換成BooleanAndExpression 運行一下 看看執(zhí)行結果 //可嘗試將LiteralExpression中實例化的參數改成其他值看看運算結果,或者直接將EqualsExpression對象換成BooleanOrExpression 或BooleanAndExpression new EqualsExpression(new LiteralExpression('four'),new LiteralExpression('four')), new EqualsExpression(new LiteralExpression('b'),new LiteralExpression('4')) ); $statement->interpret($context); if($context->lookup($statement)){ echo '條件成立'; } else { echo '條件不成立'; }
客戶端代碼二:
$context = new InterpreterContext(); $statement = new BooleanOrExpression( new BooleanAndExpression( new EqualsExpression(new LiteralExpression('4'),new LiteralExpression('4')), new EqualsExpression(new LiteralExpression('4'),new LiteralExpression('4')) ), new EqualsExpression(new LiteralExpression('b'),new LiteralExpression('4')) ); $statement->interpret($context); if($context->lookup($statement)){ echo '條件成立'; } else { echo '條件不成立'; }
客戶端代碼三:
這是原文的客戶端代碼實例和上述客戶端代碼的區(qū)別在于使用了變量表達式VariableExpression
$context = new InterpreterContext(); $input = new VariableExpression('input'); //這里定義了一個變量input 但并未賦值 $statement = new BooleanOrExpression( new EqualsExpression($input,new LiteralExpression('four')), //這里變量表達式和文字表達式的值將進行一個是否相等的比較 new EqualsExpression($input,new LiteralExpression('4')) ); foreach (array("four","4","52") as $val){ $input->setValue($val); //對input這個變量賦值 print "變量input的值為:$val:<br/>"; $statement->interpret($context); //進行比較并將比較結果存入InterpreterContext對象實例 if($context->lookup($statement)){ //獲取比較的結果 print "條件成立 <br/>"; } else { print "條件不成立 <br/>"; } }
關于怎么在PHP項目中實現一個解釋器模式就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。