本文实例讲述了php设计模式之解释器(interpreter)模式。分享给大家供大家参考,具体如下:
解释器模式,它是什么呢?
意思就是,给定一个语言, 定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子,这是最实在的一种说法。
我们还可以理解为它是用于分析一个实体的关键元素,并且针对每个元素提供自己的解释或相应动作。解释器模式非常常用,比如php的模板引擎 就是非常常见的一种解释器模。
咱来看一个网上找的最简单的实例:
<?php //解释器模式 用于分析一个实体的关键元素,并且针对每个元素提供自己的解释或相应动作 //解释器模式非常常用,比如php的模板引擎 就是非常常见的一种解释器模式 class template { private $left = '<!--{'; private $right = '}-->'; public function run($str) { return $this->init($str, $this->left, $this->right); } /** * 模板驱动-默认的驱动 * @param string $str 模板文件数据 * @return string */ private function init($str, $left, $right) { $pattern = array('/'.$left.'/', '/'.$right.'/'); $replacement = array('', ''); return preg_replace($pattern, $replacement, $str); } } $str = "这是一个模板类,简单的模板类,标题为:<!--{hello world}-->"; $template = new template; echo $template->run($str);
通过上述实例,大家对于解释器模式肯定有了自己的一个简单理解,我们接下来就看下这个解释器所包含的角色:
完事,咱在网上看的,对于解释器(interpreter)模式,还有另外一种说法,那就是它包括一个具有复合类分层结构的文法表现,规则是映射到类,跟随在文法后面的表达式可以被转换成一个抽象的语法树,除了复合模式的实例对象图外,没有别的内容。
树是一个抽象的名词,因为实际上大多数时候它是一个表达式的抽象表现,它忽略了可能有一个字符串,也可能有一个数据结构的具体表达式,(例如,在php中,“a”和“\x41”是相同抽象字面值的不同具体表现),通过逻辑规则解耦结果,使解释过程大大简化。
但是,对于简单的语法,解释器添加一个规则就象添加一个类那样容易,但解释器没有解决从具体表现形式到抽象语法树的转换,这是由其它服务完成的。
解释器模式旨在为一个简单的抽象表达式(abstractexpression)方法(解释器操作)实现利用复合分层结构,解释器操作的参数通常统称为上下文,对于给定的一个方法,它们通常被计算值代替,或它们对某些操作可能不存在。
同样,当包含一个解释器时,复合模式的叶子和容器参与者名称会不一样,这些名称反映了它们所扮演的角色:终结符(terminal)或非终结符(nonterminal)表达式。
来看下参与者:
◆客户端(client):使用解释操作。
◆抽象表达式(abstractexpression):基于一个表达式树抽象。
◆非终结符表达式(nonterminalexpression):递归地包含其它抽象表达式(abstractexpression实例)的表达式。
◆终结符表达式(terminalexpression):不能够进一步简化的表达式。
我们来看下《设计模式》一书针对这个模式提供的一个扩展示例,是一个网友使用数学表达式替换布尔表达式重新改造了一下,因此这个例子解决了一个数学表达式的展现,它的evaluate( )被分离在一个不同的concreteexpression类中,如下:
/** * abstractexpression. all implementations of this interface * are concreteexpressions. */ interface mathexpression { /** * calculates the value assumed by the expression. * note that $values is passed to all expression but it * is used by variable only. this is required to abstract * away the tree structure. */ public function evaluate(array $values); } /** * a terminal expression which is a literal value. */ class literal implements mathexpression { private $_value; public function __construct($value) { $this->_value = $value; } public function evaluate(array $values) { return $this->_value; } } /** * a terminal expression which represents a variable. */ class variable implements mathexpression { private $_letter; public function __construct($letter) { $this->_letter = $letter; } public function evaluate(array $values) { return $values[$this->_letter]; } } /** * nonterminal expression. */ class sum implements mathexpression { private $_a; private $_b; public function __construct(mathexpression $a, mathexpression $b) { $this->_a = $a; $this->_b = $b; } public function evaluate(array $values) { return $this->_a->evaluate($values) + $this->_b->evaluate($values); } } /** * nonterminal expression. */ class product implements mathexpression { private $_a; private $_b; public function __construct(mathexpression $a, mathexpression $b) { $this->_a = $a; $this->_b = $b; } public function evaluate(array $values) { return $this->_a->evaluate($values) * $this->_b->evaluate($values); } } // 10(a + 3) $expression = new product(new literal(10), new sum(new variable('a'), new literal(3))); echo $expression->evaluate(array('a' => 4)), "\n"; // adding new rules to the grammar is easy: // e.g. power, subtraction... // thanks to the composite, manipulation is even simpler: // we could add substitute($letter, mathexpression $expr) // to the interface...
咱最后再分享一个实例,如下:
<?php header("content-type:text/html;charset=utf-8"); //环境角色,定义要解释的全局内容 class expression{ public $content; function getcontent(){ return $this->content; } } //抽象解释器 abstract class abstractinterpreter{ abstract function interpret($content); } //具体解释器,实现抽象解释器的抽象方法 class chineseinterpreter extends abstractinterpreter{ function interpret($content){ for($i=1;$i<count($content);$i++){ switch($content[$i]){ case '0': echo "没有人<br>";break; case "1": echo "一个人<br>";break; case "2": echo "二个人<br>";break; case "3": echo "三个人<br>";break; case "4": echo "四个人<br>";break; case "5": echo "五个人<br>";break; case "6": echo "六个人<br>";break; case "7": echo "七个人<br>";break; case "8": echo "八个人<br>";break; case "9": echo "九个人<br>";break; default:echo "其他"; } } } } class englishinterpreter extends abstractinterpreter{ function interpret($content){ for($i=1;$i<count($content);$i++){ switch($content[$i]){ case '0': echo "this is nobody<br>";break; case "1": echo "this is one people<br>";break; case "2": echo "this is two people<br>";break; case "3": echo "this is three people<br>";break; case "4": echo "this is four people<br>";break; case "5": echo "this is five people<br>";break; case "6": echo "this is six people<br>";break; case "7": echo "this is seven people<br>";break; case "8": echo "this is eight people<br>";break; case "9": echo "this is nine people<br>";break; default:echo "others"; } } } } //封装好的对具体解释器的调用类,非解释器模式必须的角色 class interpreter{ private $interpreter; private $content; function __construct($expression){ $this->content = $expression->getcontent(); if($this->content[0] == "chinese"){ $this->interpreter = new chineseinterpreter(); }else{ $this->interpreter = new englishinterpreter(); } } function execute(){ $this->interpreter->interpret($this->content); } } //测试 $expression = new expression(); $expression->content = array("chinese",3,2,4,4,5); $interpreter = new interpreter($expression); $interpreter->execute(); $expression = new expression(); $expression->content = array("english",1,2,3,0,0); $interpreter = new interpreter($expression); $interpreter->execute(); ?>
结果:
三个人
二个人
四个人
四个人
五个人
this is one people
this is two people
this is three people
this is nobody
this is nobody
好啦,本次记录就到这里了。
如对本文有疑问, 点击进行留言回复!!
20.7.17 笔记算数运算符 复合运算符重载 比较运算重载 多态 设计原则 类的单一职责 依赖倒置 组合复用原则 里氏替换 迪米特法则 矩阵转置原理
网友评论