当前位置:首页 > PHP教程 > php高级应用 > 列表

PHP设计模式之解释器(Interpreter)模式入门与应用详解

发布:smiling 来源: PHP粉丝网  添加日期:2022-01-26 09:56:25 浏览: 评论:0 

本文实例讲述了PHP设计模式之解释器(Interpreter)模式,分享给大家供大家参考,具体如下:

解释器模式,它是什么呢?

意思就是,给定一个语言, 定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子,这是最实在的一种说法。

我们还可以理解为它是用于分析一个实体的关键元素,并且针对每个元素提供自己的解释或相应动作。解释器模式非常常用,比如PHP的模板引擎 就是非常常见的一种解释器模。

咱来看一个网上找的最简单的实例:

  1. <?php 
  2. //解释器模式 用于分析一个实体的关键元素,并且针对每个元素提供自己的解释或相应动作 
  3. //解释器模式非常常用,比如PHP的模板引擎 就是非常常见的一种解释器模式 
  4. class template { 
  5.    
  6.  private $left = '<!--{'
  7.  private $right = '}-->'
  8.    
  9.  public function run($str) { 
  10.  return $this->init($str$this->left, $this->right); 
  11.  } 
  12.    
  13.  /** 
  14.  * 模板驱动-默认的驱动 
  15.  * @param string $str 模板文件数据 
  16.  * @return string 
  17.  */ 
  18.  private function init($str$left$right) { 
  19.  $pattern = array('/'.$left.'/''/'.$right.'/'); 
  20.  $replacement = array(''''); 
  21.  return preg_replace($pattern$replacement$str); 
  22.  } 
  23. $str = "这是一个模板类,简单的模板类,标题为:<!--{Hello World}-->"
  24. $template = new template; 
  25. echo $template->run($str); 

通过上述实例,大家对于解释器模式肯定有了自己的一个简单理解,我们接下来就看下这个解释器所包含的角色:

环境角色:定义解释规则的全局信息。

抽象解释器::定义了部分解释具体实现,封装了一些由具体解释器实现的接口。

具体解释器(MusicNote):实现抽象解释器的接口,进行具体的解释执行。

完事,咱在网上看的,对于解释器(Interpreter)模式,还有另外一种说法,那就是它包括一个具有复合类分层结构的文法表现,规则是映射到类,跟随在文法后面的表达式可以被转换成一个抽象的语法树,除了复合模式的实例对象图外,没有别的内容。

树是一个抽象的名词,因为实际上大多数时候它是一个表达式的抽象表现,它忽略了可能有一个字符串,也可能有一个数据结构的具体表达式,(例如,在PHP中,“A”和“\x41”是相同抽象字面值的不同具体表现),通过逻辑规则解耦结果,使解释过程大大简化。

但是,对于简单的语法,解释器添加一个规则就象添加一个类那样容易,但解释器没有解决从具体表现形式到抽象语法树的转换,这是由其它服务完成的。

解释器模式旨在为一个简单的抽象表达式(AbstractExpression)方法(解释器操作)实现利用复合分层结构,解释器操作的参数通常统称为上下文,对于给定的一个方法,它们通常被计算值代替,或它们对某些操作可能不存在。

同样,当包含一个解释器时,复合模式的叶子和容器参与者名称会不一样,这些名称反映了它们所扮演的角色:终结符(terminal)或非终结符(nonterminal)表达式。

来看下参与者:

◆客户端(Client):使用解释操作。

◆抽象表达式(AbstractExpression):基于一个表达式树抽象。

◆非终结符表达式(NonTerminalExpression):递归地包含其它抽象表达式(AbstractExpression实例)的表达式。

◆终结符表达式(TerminalExpression):不能够进一步简化的表达式。

我们来看下《设计模式》一书针对这个模式提供的一个扩展示例,是一个网友使用数学表达式替换布尔表达式重新改造了一下,因此这个例子解决了一个数学表达式的展现,它的evaluate( )被分离在一个不同的ConcreteExpression类中,如下:

  1. /**  
  2.  * AbstractExpression. All implementations of this interface  
  3.  * are ConcreteExpressions.  
  4.  */ 
  5. interface MathExpression  
  6. {  
  7.  /**  
  8.   * Calculates the value assumed by the expression.  
  9.   * Note that $values is passed to all expression but it  
  10.   * is used by Variable only. This is required to abstract  
  11.   * away the tree structure.  
  12.   */ 
  13.  public function evaluate(array $values);  
  14. }  
  15.    
  16. /**  
  17.  * A terminal expression which is a literal value.  
  18.  */ 
  19. class Literal implements MathExpression  
  20. {  
  21.  private $_value;  
  22.    
  23.  public function __construct($value)  
  24.  {  
  25.   $this->_value = $value;  
  26.  }  
  27.    
  28.  public function evaluate(array $values)  
  29.  {  
  30.   return $this->_value;  
  31.  }  
  32. }  
  33.    
  34. /**  
  35.  * A terminal expression which represents a variable.  
  36.  */ 
  37. class Variable implements MathExpression  
  38. {  
  39.  private $_letter;  
  40.    
  41.  public function __construct($letter)  
  42.  {  
  43.   $this->_letter = $letter;  
  44.  }  
  45.    
  46.  public function evaluate(array $values)  
  47.  {  
  48.   return $values[$this->_letter];  
  49.  }  
  50. }  
  51.    
  52. /**  
  53.  * Nonterminal expression.  
  54.  */ 
  55. class Sum implements MathExpression  
  56. {  
  57.  private $_a;  
  58.  private $_b;  
  59.    
  60.  public function __construct(MathExpression $a, MathExpression $b)  
  61.  {  
  62.   $this->_a = $a;  
  63.   $this->_b = $b;  
  64.  }  
  65.    
  66.  public function evaluate(array $values)  
  67.  {  
  68.   return $this->_a->evaluate($values) + $this->_b->evaluate($values);  
  69.  }  
  70. }  
  71.    
  72. /**  
  73.  * Nonterminal expression.  
  74.  */ 
  75. class Product implements MathExpression  
  76. {  
  77.  private $_a;  
  78.  private $_b;  
  79.    
  80.  public function __construct(MathExpression $a, MathExpression $b)  
  81.  {  
  82.   $this->_a = $a;  
  83.   $this->_b = $b;  
  84.  }  
  85.    
  86.  public function evaluate(array $values)  
  87.  {  
  88.   return $this->_a->evaluate($values) * $this->_b->evaluate($values);  
  89.  }  
  90. }  
  91.    
  92. // 10(a + 3)  
  93. $expression = new Product(new Literal(10), new Sum(new Variable('a'), new Literal(3)));  
  94. echo $expression->evaluate(array('a' => 4)), "\n";  
  95. // adding new rules to the grammar is easy:  
  96. // e.g. Power, Subtraction...  
  97. // thanks to the Composite, manipulation is even simpler:  
  98. // we could add substitute($letter, MathExpression $expr)  
  99. // to the interface...  

咱最后再分享一个实例,如下:

  1. <?php 
  2. header("Content-type:text/html;Charset=utf-8"); 
  3.    
  4. //环境角色,定义要解释的全局内容 
  5. class Expression{ 
  6.  public $content
  7.  function getContent(){ 
  8.   return $this->content; 
  9.  } 
  10.    
  11. //抽象解释器 
  12. abstract class AbstractInterpreter{ 
  13.  abstract function interpret($content); 
  14.    
  15. //具体解释器,实现抽象解释器的抽象方法 
  16. class ChineseInterpreter extends AbstractInterpreter{ 
  17.  function interpret($content){ 
  18.   for($i=1;$i<count($content);$i++){ 
  19.    switch($content[$i]){ 
  20.    case '0'echo "没有人<br>";break
  21.    case "1"echo "一个人<br>";break
  22.    case "2"echo "二个人<br>";break
  23.    case "3"echo "三个人<br>";break
  24.    case "4"echo "四个人<br>";break
  25.    case "5"echo "五个人<br>";break
  26.    case "6"echo "六个人<br>";break
  27.    case "7"echo "七个人<br>";break
  28.    case "8"echo "八个人<br>";break
  29.    case "9"echo "九个人<br>";break
  30.    default:echo "其他"
  31.    } 
  32.   } 
  33.  } 
  34. class EnglishInterpreter extends AbstractInterpreter{ 
  35.  function interpret($content){ 
  36.   for($i=1;$i<count($content);$i++){ 
  37.     switch($content[$i]){ 
  38.     case '0'echo "This is nobody<br>";break
  39.     case "1"echo "This is one people<br>";break
  40.     case "2"echo "This is two people<br>";break
  41.     case "3"echo "This is three people<br>";break
  42.     case "4"echo "This is four people<br>";break
  43.     case "5"echo "This is five people<br>";break
  44.     case "6"echo "This is six people<br>";break
  45.     case "7"echo "This is seven people<br>";break
  46.     case "8"echo "This is eight people<br>";break
  47.     case "9"echo "This is nine people<br>";break
  48.     default:echo "others"
  49.    } 
  50.   } 
  51.  } 
  52.    
  53. //封装好的对具体解释器的调用类,非解释器模式必须的角色 
  54. class Interpreter{ 
  55.   private $interpreter
  56.   private $content
  57.   function __construct($expression){ 
  58.   $this->content = $expression->getContent(); 
  59.   if($this->content[0] == "Chinese"){ 
  60.     $this->interpreter = new ChineseInterpreter(); 
  61.    }else
  62.     $this->interpreter = new EnglishInterpreter(); 
  63.    } 
  64.   } 
  65.   function execute(){ 
  66.    $this->interpreter->interpret($this->content); 
  67.   } 
  68.    
  69. //测试 
  70. $expression = new Expression(); 
  71. $expression->content = array("Chinese",3,2,4,4,5); 
  72. $interpreter = new Interpreter($expression); 
  73. $interpreter->execute(); 
  74.    
  75. $expression = new Expression(); 
  76. $expression->content = array("English",1,2,3,0,0); 
  77. $interpreter = new Interpreter($expression); 
  78. $interpreter->execute(); 
  79. ?> 

结果:

  1. 三个人 
  2. 二个人 
  3. 四个人 
  4. 四个人 
  5. 五个人 
  6. This is one people 
  7. This is two people 
  8. This is three people 
  9. This is nobody 
  10. This is nobody 

好啦,本次记录就到这里了。

Tags: PHP设计模式 Interpreter

分享到: