PHP设计模式——解释器模式

声明:本系列博客参考资料《大话设计模式》,作者程杰。

        解释器模式:Given a language, define arepresentation for its grammar along with an interpreter that uses therepresentation to interpret sentences in the language。给定一个语言,
定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。

       类图:

      

  

             角色:  

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

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

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

       核心代码:(注意:需要开启extension=php_mbstring.dll扩展)

      

<?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;
    }
}

        调用客户端代码:

      

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语法分析,不过该部分逐渐被专用工具所取代。

         欢迎关注我的视频课程,地址如下,谢谢。

   PHP面向对象设计模式

时间: 2024-09-17 04:54:59

PHP设计模式——解释器模式的相关文章

20、Python与设计模式--解释器模式

一.模拟吉他 要开发一个自动识别谱子的吉他模拟器,达到录入谱即可按照谱发声的效果.除了发声设备外(假设已完成),最重要的就是读谱和译谱能力了.分析其需求,整个过程大致上分可以分为两部分:根据规则翻译谱的内容:根据翻译的内容演奏.我们用一个解释器模型来完成这个功能. class PlayContext(): play_text = None class Expression(): def interpret(self, context): if len(context.play_text) ==

Java设计模式--解释器模式

解释器模式 给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子. Interpreter Pattern Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language. 类图 模式的结构与使用 解释器模式的结构中包

PHP设计模式之解释器模式

解释器: 解释器设计模式用于分析一个实体的关键元素,并且针对每个元素都提供自己的解释或相应的动作. 解释器设计模式最常用于PHP/HTML 模板系统. <?php        class User {            protected $_username = "";            public function __construct($username) {                $this->_username = $username;  

Java设计模式编程之解释器模式的简单讲解_java

0.解释器(Interpreter)模式定义 :给定一门语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中句子. 属于行为型模式. 解释器模式在实际的系统开发中使用的非常少,因为它会引起效率.性能以及维护等问题. 解释器模式的通用类图如图所示. 1.解释器模式的优点 解释器是一个简单语法分析工具,它最显著的优点就是扩展性,修改语法规则只要修改相应的非终结符表达式就可以了,若扩展语法,则只要增加非终结符类就可以了. 2.解释器模式的缺点 解释器模式会引起类膨胀:每个语法

解析Java的设计模式编程之解释器模式的运用_java

定义:给定一种语言,定义他的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中句子.类型:行为类模式类图: 解释器模式是一个比较少用的模式,本人之前也没有用过这个模式.下面我们就来一起看一下解释器模式.  解释器模式的结构抽象解释器:声明一个所有具体表达式都要实现的抽象接口(或者抽象类),接口中主要是一个interpret()方法,称为解释操作.具体解释任务由它的各个实现类来完成,具体的解释器分别由终结符解释器TerminalExpression和非终结符解释器Nontermina

深入解析C++设计模式编程中解释器模式的运用_C 语言

解释器模式(interpreter),给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子. 解释器模式需要解决的是,如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子.这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题.当有一个语言需要解释执行,并且你可将该语言中的句子表示为一个抽象语法树时,可使用解释器模式.用了解释器模式,就意味着可以很容易地改变和扩展文法,因为该模式使用类来表示文法规则,

乐在其中设计模式(C#) - 解释器模式(Interpreter Pattern)

原文:乐在其中设计模式(C#) - 解释器模式(Interpreter Pattern)[索引页][源码下载] 乐在其中设计模式(C#) - 解释器模式(Interpreter Pattern) 作者:webabcd 介绍 给定一个语言, 定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子. 示例 有一个Message实体类,某个类对它的操作有Get()方法.现在要求用具有某一规则的中文语法来执行这个操作. MessageModel using System;usin

C++设计模式之解释器模式_C 语言

前言 那日,闲的无聊,上了一个在线编程学习网站:最近那个在线编程学习网站很火啊:之前,盖茨.扎克伯格等大人物都来宣传了,思想是人人都应该学习编程:我一想就这算怎么回事啊?这要是在中国,还让人活不?话题不扯开了,还是说我上了那个在线编程网站吧,首先是给你玩一个小游戏,激发你对编程的兴趣.游戏是这样的,网页上有一个编辑框,屏幕上有一只小狗,比如你在编辑框中输入这样的句子:down run 10:按下回车,这个时候,你就看到屏幕上的小狗向下跑动了10个方格大小的长度:你再输入up walk 5,按下回

PHP设计模式之解释器模式的深入解析_php技巧

解释器(Interpreter)模式,它包括一个具有复合类分层结构的文法表现,规则是映射到类,跟随在文法后面的表达式可以被转换成一个抽象的语法树,除了复合模式的实例对象图外,没有别的内容. 树是一个抽象的名词,因为实际上大多数时候它是一个表达式的抽象表现,它忽略了可能有一个字符串,也可能有一个数据结构的具体表达式,(例如,在PHP中,"A"和"\x41"是相同抽象字面值的不同具体表现),通过逻辑规则解耦结果,使解释过程大大简化. 解释器不是一个很常见的模式,但对于简