您的位置 首页 php

设计模式-解释器模式

首先欢迎大家关注小编哦~~

接下来为大家带来解释器模式。

解释器模式:

给定一个语言, 定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。

角色:

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

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

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

<?php
/**
* Created by PhpStorm.
* User: Jiang
* Date: 2015/5/31
* Time: 15:51
*//**环境角色
* Class PlayContent
*/class PlayContent
{
public $content;
}
/**抽象解析器
* Class IExpress
*/abstract class IExpress
{
//-----------------解释器----------------
public function Translate(PlayContent $play_content)
 {
if (empty($play_content->content)) {
return false;
}
$key = mb_substr($play_content->content, 0, 1);
$play_content->content = mb_substr($play_content->content, 2);
$val = mb_substr($play_content->content, 0, mb_strpos($play_content->content, ' '));
$play_content->content = mb_substr($play_content->content, mb_strpos($play_content->content, ' ') + 1);
return $this->Excute($key, $val);
}
public abstract function Excute($key, $val);
}
//------------------------具体解析器-------------
/**音符
* Class MusicNote
*/class MusicNote extends IExpress
{
public function Excute($key, $val)
 {
$note = "";
switch ($key) {
case "C":
$note = "1";
 break ;
case "D":
$note = "2";
break;
case "E":
$note = "3";
break;
case "F":
$note = "4";
break;
case "G":
$note = "5";
break;
case "A":
$note = "6";
break;
case "B":
$note = "7";
break;
}
return $note;
}
}
/**音阶
* Class MusicScale
*/class MusicScale extends IExpress
{
public function Excute($key, $val)
 {
$scale = "";
switch ($val) {
case "1":
$scale = "低音";
break;
case "2":
$scale = "中音";
break;
case "3":
$scale = "高音";
break;
}
return $scale;
}
} 

调用客户端代码:

<?php
 header ("Content-Type:text/html;charset=utf-8");
//-------------------------解释器模式-------------------------------
require_once "./Interpreter/Interpreter.php";
$play_content = new PlayContent();
$play_content->content = "O 2 E 0.5 G 0.5 A 3 E 0.5 G 0.5 D 3 E 0.5 G 0.5 A 0.5 O 3 C 1 O 2 A 0.5 G 1 C 0.5 E 0.5 D 3 ";
$interpreter = null;
try {
while (!empty($play_content->content)) {
$str = mb_substr($play_content->content, 0, 1);
switch ($str) {
case "O":
$interpreter = new MusicScale();
break;
case "C":
case "D":
case "E":
case "F":
case "G":
case "A":
case "B":
case "P":
$interpreter = new MusicNote();
break;
}
echo $interpreter->Translate($play_content) . '::';
}
} catch (Exception $e) {
echo $e->getMessage();
}
优点: 

解释器是一个简单语法分析工具,它最显著的优点就是扩展性,修改语法规则只要修改相应的非终结符表达式就可以了,若扩展语法,则只要增加非终结符类就可以了。

缺点:

1.解释器模式会引起类膨胀

2.每个语法都要产生一个非终结符表达式,语法规则比较复杂时,就可能产生大量的类文件,为维护带来了非常多的麻烦。

3.解释器模式采用递归调用方法

每个非终结符表达式只关心与自己有关的表达式,每个表达式需要知道最终的结果,必须一层一层地剥茧,无论是面向过程的语言还是面向对象的语言,递归都是在必要条件下使用的,它导致调试非常复杂。想想看,如果要排查一个语法错误,我们是不是要一个一个断点的调试下去,直到最小的语法单元。

效率问题

解释器模式由于使用了大量的循环和递归,效率是个不容忽视的问题,特别是用于解析复杂、冗长的语法时,效率是难以忍受的。

适用场景:

1、重复发生的问题可以使用解释器模式

例如,多个应用服务器,每天产生大量的日志,需要对日志文件进行分析处理,由于各个服务器的日志格式不同,但是数据要素是相同的,按照解释器的说法就是终结符表达式都是相同的,但是非终结符表达式就需要制定了。在这种情况下,可以通过程序来一劳永逸地解决该问题。

2、一个简单语法需要解释的场景

为什么是简单?文法规则越多,复杂度越高,而且类间还要进行递归调用,不是一般地复杂。想想看,多个类之间的调用你需要什么样的耐心和信心去排查问题。因此,解释器模式一般用来解析比较标准的字符集,例如SQL语法分析,不过该部分逐渐被专用工具所取代。

文章来源:智云一二三科技

文章标题:设计模式-解释器模式

文章地址:https://www.zhihuclub.com/79583.shtml

关于作者: 智云科技

热门文章

网站地图