国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > PHP > 正文

PHP解釋器模式用法詳解

2020-03-22 18:56:27
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友
下面小編就為大家?guī)?lái)一篇老生常談PHPhtml' target='_blank'>面向?qū)ο?/u>之解釋器模式。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

最近在看 “深入PHP面向?qū)ο竽J脚c實(shí)踐” ,學(xué)習(xí)書(shū)中的內(nèi)容后瞬間覺(jué)得自己有點(diǎn)高大上了,哈 ! 其實(shí)還是個(gè)菜B。相信也會(huì)有新手朋友在看這本(我自己也是新手),對(duì)書(shū)中我個(gè)人認(rèn)為比較難的內(nèi)容的學(xué)習(xí)心得就想拿出來(lái)分享和交流,1是希望對(duì)自己所學(xué)知識(shí)能夠起到鞏固和加深理解的作用 2是希望對(duì)看到本文且感興趣的新手朋友一些幫助。

這部分內(nèi)容看了好幾遍了代碼也跟著敲了幾遍,估計(jì)本文想要實(shí)現(xiàn)的功能大概就是用戶在web頁(yè)面上輸入一些內(nèi)容,然后通過(guò)后臺(tái)程序解析后進(jìn)行回復(fù)(感覺(jué)就是在廢話)。例如我在前臺(tái)web頁(yè)面輸入框里輸入:


$input = "4";$input equals "4" or $input equals "four";

然后提交,系統(tǒng)就會(huì)回復(fù)類似 “條件成立” 或者 “條件不成立”的結(jié)果(有點(diǎn)類似直接在前臺(tái)寫(xiě)代碼并運(yùn)行,后臺(tái)解析后會(huì)返回一個(gè)結(jié)果。原書(shū)中雖然沒(méi)有講解整個(gè)前臺(tái)輸入到后臺(tái)解析的過(guò)程但我猜這個(gè)后臺(tái)解析應(yīng)該還有一個(gè)使用正則表達(dá)式提取類似上面2行代碼中關(guān)鍵字的過(guò)程)

上面這二行代碼雖然是作者發(fā)明的語(yǔ)言,但根據(jù)字面含義也不難理解,第一行是定義一個(gè)變量并賦值,第二行是對(duì)變量進(jìn)行一個(gè)判斷(變量等于4或者等于four)。

廢話不多說(shuō)來(lái)看看這個(gè)模式定義的這幾個(gè)類 (類圖請(qǐng)自行看原文):

一、interpreterContext 這個(gè)類就像一個(gè)容器 主要是用來(lái)存放和獲取需要進(jìn)行比較的值和比較的結(jié)果的,例如上述代碼中的4, four,和比較結(jié)果 “true”或“false”,保存的形式是數(shù)組即類的屬性$expressionstore,代碼如下:


class InterpreterContext{  private $expressionstore = array(); //存放比較的值和結(jié)果    function replace(Expression $exp,$value){    // 設(shè)置值    $this->expressionstore[$exp->getKey()] = $value;  }    function lookup(Expression $exp){        //獲取值    return $this->expressionstore[$exp->getKey()];  }}

這個(gè)類就像一個(gè)工具,供其他類來(lái)使用(它和其他類不存在繼承、組合或聚合的關(guān)系)。

二、Expression 這是一個(gè)表達(dá)式的抽象類,定義了抽象方法interpret() 和方法getKey()

代碼如下:


abstract class Expression {  private static $keycount = 0;  //計(jì)數(shù)用的  private $key;          //存放一個(gè)唯一值  //主要實(shí)現(xiàn)將前臺(tái)獲取到的數(shù)據(jù)存放到上述InterpreterContext類中的功能,看到下面的內(nèi)容就會(huì)發(fā)現(xiàn)繼承他的類調(diào)用了InterpreterContext類的replace()方法  abstract function interpret (InterpreterContext $context);  //獲取一個(gè)唯一值    function getKey(){           if(!isset($this->key)){      self::$keycount++;      $this->key= self::$keycount;    }    return $this->key;  }}

下面將要講到的類都將繼承這個(gè)類,并且他和OperatorExpression(操作符表達(dá)式抽象類)是一個(gè)組合的關(guān)系,也就是說(shuō)OperatorExpression在初始化時(shí)可以包含所有繼承了Expression的子類(這也是本書(shū)一直在強(qiáng)調(diào)的要面向接口編程,這個(gè)Expression就是個(gè)接口,利用這個(gè)接口可以實(shí)現(xiàn)多態(tài),不知道自己裝B說(shuō)的對(duì)不對(duì),哈! 具體可以在看看原書(shū)的類圖)

三、LiteralExpression 文字表達(dá)式類,作用就是將一個(gè)字符串保存到InterpreterContext這個(gè)小容器里,保存成一個(gè)索引數(shù)組,例如保存開(kāi)頭那二句自創(chuàng)代碼中的 4 或者 four

代碼如下:


class LiteralExpression extends Expression{  private $value;    function __construct ($value){      //初始化時(shí)傳入要保存的值    $this->value= $value;  }  function interpret(InterpreterContext $context){    //調(diào)用InterpreterContext類的replace()將$value保存到InterpreterContext這個(gè)小容器里    $context->replace($this,$this->value);  }}

四、VariableExpression 變量表達(dá)式類,和上面類的作用是一樣的只不過(guò)數(shù)據(jù)將被保存成關(guān)聯(lián)數(shù)組,關(guān)聯(lián)數(shù)組中的健是變量名,值呢就是變量的值,例如開(kāi)頭二句中的變量"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){  //用于設(shè)置變量的值    $this->val = $value;  }    function getKey(){    //這個(gè)復(fù)寫(xiě)了父類的getKey()方法,在小容器InterpreterContext的lookup()方法調(diào)用這個(gè)類的實(shí)例的getKey()方法時(shí) 它將返回一個(gè)字符串(即變量名)而不是數(shù)字索引    return $this->name;  }}

五、OperatorExpression 操作符表達(dá)式抽象基類,此類繼承且組合了Expression抽象基類,實(shí)現(xiàn)的interpret()方法主要保存表達(dá)式的計(jì)算結(jié)果

代碼如下:


abstract class OperatorExpression extends Expression{protected $l_op;  //表達(dá)式左邊的值protected $r_op;  //表達(dá)式右邊的值function __construct (Expression $l_op,Expression $r_op){    //初始化時(shí)可組合繼承了Expression類的子類實(shí)例$this->l_op = $l_op;$this->r_op = $r_op;}function interpret(InterpreterContext $context){  //主要用于保存表達(dá)試的結(jié)果(保存到InterpreterContext 類的實(shí)例中)$this->l_op->interpret($context);        //將Expression子類實(shí)例的值或計(jì)算結(jié)果保存到InterpreterContext 類的實(shí)例中$this->r_op->interpret($context);$result_l = $context->lookup($this->l_op);    //獲取上一步的值或計(jì)算結(jié)果$result_r = $context->lookup($this->r_op);$this->doInterpret($context,$result_l,$result_r);  //具體的比較運(yùn)算由繼承的子類來(lái)實(shí)現(xiàn)}protected abstract function doInterpret(InterpreterContext $context,$result_l,$result_r);}

六、EqualsExpression、BooleanOrExpression、BooleanAndExpression,分別為繼承了OperatorExpression 抽象基類的相等表達(dá)式、或表達(dá)式、與表達(dá)式只有一個(gè)方法doInterpret()內(nèi)部調(diào)用了InterpreterContext類的replace()方法將表達(dá)式的計(jì)算結(jié)果保存到InterpreterContext類的實(shí)例中

代碼如下:


//相等表達(dá)式class EqualsExpression extends OperatorExpression {protected function doInterpret(InterpreterContext $context,$result_l,$result_r){$context->replace($this,$result_l == $result_r);}}//或表達(dá)式class BooleanOrExpression extends OperatorExpression{protected function doInterpret(InterpreterContext $context,$result_l,$result_r){$context->replace($this,$result_l || $result_r);}}//與表達(dá)式class BooleanAndExpression extends OperatorExpression{protected function doInterpret(InterpreterContext $context,$result_l,$result_r){$context->replace($this,$result_l && $result_r);}}

到此為止此模式相關(guān)的類就介紹完畢,上述代碼都是進(jìn)過(guò)測(cè)試的,可直接復(fù)制粘貼運(yùn)行來(lái)查看結(jié)果,現(xiàn)在我們就來(lái)看看客戶端代碼:

客戶端代碼一:


$context = new InterpreterContext();$statement = new BooleanOrExpression (  //可嘗試將此操作符表達(dá)式換成BooleanAndExpression 運(yùn)行一下 看看執(zhí)行結(jié)果//可嘗試將LiteralExpression中實(shí)例化的參數(shù)改成其他值看看運(yùn)算結(jié)果,或者直接將EqualsExpression對(duì)象換成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 '條件不成立';}

客戶端代碼三:

這是原文的客戶端代碼實(shí)例和上述客戶端代碼的區(qū)別在于使用了變量表達(dá)式VariableExpression


$context = new InterpreterContext();    $input = new VariableExpression('input');  //這里定義了一個(gè)變量input 但并未賦值$statement = new BooleanOrExpression(new EqualsExpression($input,new LiteralExpression('four')),  //這里變量表達(dá)式和文字表達(dá)式的值將進(jìn)行一個(gè)是否相等的比較new EqualsExpression($input,new LiteralExpression('4')));foreach (array("four","4","52") as $val){$input->setValue($val);        //對(duì)input這個(gè)變量賦值print "變量input的值為:$val:<br/>";$statement->interpret($context);  //進(jìn)行比較并將比較結(jié)果存入InterpreterContext對(duì)象實(shí)例if($context->lookup($statement)){  //獲取比較的結(jié)果print "條件成立 <br/>";} else {print "條件不成立 <br/>";}}

上述代碼經(jīng)過(guò)測(cè)試都可以正常運(yùn)行,有需要的朋友可以復(fù)制下來(lái),運(yùn)行一下看看結(jié)果。

以上就是PHP解釋器模式用法詳解的詳細(xì)內(nèi)容,更多請(qǐng)關(guān)注 其它相關(guān)文章!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 霸州市| 鹿泉市| 江源县| 永寿县| 潞西市| 汶上县| 香港| 威海市| 万全县| 桓台县| 鄂伦春自治旗| 辽阳市| 化德县| 凯里市| 南汇区| 广饶县| 泾川县| 龙川县| 苍山县| 仙桃市| 桑日县| 株洲市| 高雄县| 阳泉市| 武邑县| 道真| 砀山县| 南岸区| 专栏| 大关县| 巴林左旗| 苏州市| 靖安县| 大名县| 罗源县| 偃师市| 平阴县| 朝阳市| 城口县| 黄梅县| 岢岚县|