专栏首页决胜机器学习设计模式专题(二十三) ——解释器模式

设计模式专题(二十三) ——解释器模式

设计模式专题(二十三)——解释器模式

(原创内容,转载请注明来源,谢谢)

一、概述

解释器模式(interpreter)是给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。

如果某一特定类型发生的频率足够高,那么就可以将问题的各个实例表述为一个简单语言中的句子,并构建解释器,通过解释句子,解释器来解决问题。

例如字符串匹配,大多数语言用到的正则表达式,就可以理解成一种解释器模式,字符串是待匹配字符的集合,而表达式是一种匹配模式。

当有一个语言需要解释器执行,并且可以将该语言中的句子表示为抽象语法树,则可以使用解释器模式。解释器模式可以容易的改变和扩展文法,由于该模式用类表示文法规则,因此可以继承类来改变文法,也比较容易实现文法。因为定义抽象语法树中各节点的类的实现大体相似,这些类都易于直接编写。

二、类图

三、设计实现

1、设计方案

解释器模式包含以下5个模块:

1)文本类,用于提供文本。

2)解释器抽象类,定义解释器必须的内容。

3)解释器具体类,可以根据实际情况进行解释。

4)工厂类,类图中没有,可以在客户端与解释器抽象类之间加一个工厂类,由工厂类判断该如何调用抽象解释器,这样可以使得修改代码避免修改客户端。

5)客户端代码。

2、设计内容

sql查询的类,可以有各种类型的拼接sql的方式,这里用解释器模式初步实现部分的方法。

这里仅实现两个拼接where语句的类。

原生的是where|and|compare|a|equal|b形式。

1)where(‘and’,’compare’, ’a’, ’equal’, ’b’);表示where a=b或者...and a=b

2)where(‘or’, ‘like’,‘c’, ‘%’, ‘dd’, ‘%’);表示where c like ‘%d%’ 或者… or c like ‘%d%’

3、具体实现

<?php
//解释器模式——模拟where语句
//1.文本类
class Context{
         private$rawContents;//翻译前
         private$arrMid;//翻译中的临时变量
         private$interContents;//翻译后,失败时为##error:msg##
         publicfunction __construct($rawStr){
                   $this->rawContents= $rawStr;
                   $this->interContents= '';
                   $this->arrMid= array();
         }
         publicfunction getRaw(){
                   return$this->rawContents;
         }
         publicfunction getInter(){
                   return$this->interContents;
         }
         publicfunction getArrMid(){
                   return$this->arrMid;
         }
         publicfunction setRaw($rawStr){
                   $this->rawContents= $rawStr;
         }
         publicfunction setInter($interStr){
                   $this->interContents= $interStr;
         }
         publicfunction setArrMid(array $arr){
                   $this->arrMid= $arr;
         }
}
//2.解释器抽象类
abstract class Interpreter{
         protected$result = '';
         protected$context;
         publicfunction __construct(Context $context){
                   $this->context= $context;
         }
         publicfunction setContext(Context $context){
                   $this->context= $context;
         }
         publicfunction explain(){}
         publicfunction getResult(){
                   return$this->result;
         }
         protectedfunction setContextInter($interStr){
                   $this->context->setInter($interStr);
                   return$this->context;
         }       
}
//3.具体解释器1--where的比较解释器
class InterpreterCompare extendsInterpreter{
         publicfunction __construct(Context $context){
                   praent::__construct(Context$context);
         }
         publicfunction explain(){
                   $arrMid= $this->context->getArrMid();
                   if(5!= count($arrMid)){
                            $this->setContextInter('##error:wrongcompare type##');
                   }
                   switch($arrMid[3]) {
                            case'equal':
                                     $this->result= $arrMid[2] . '=' . $arrMid[4];
                                     $this->setContextInter($this->result);
                                     break;
                            case'large':
                                     $this->result= $arrMid[2] . '>' . $arrMid[4];
                                     $this->setContextInter($this->result);
                            default:
                                     $this->setContextInter('##error:wrongcompare node##');
                                     break;
                   }
                   return$this->context;
         }
}
//4.具体解释器2--where的like解释器
class InterpreterLike extends Interpreter{
         publicfunction __construct(Context $context){
                   praent::__construct(Context$context);
         }
         publicfunction explain(){
                   $arrMid= $this->context->getArrMid();
                   if(6!= count($arrMid)){
                            $this->setFalse('##error:wrongcompare type##');
                   }
                   $this->result= $arrMid[2];
                   $this->result.= '%' == $arrMid[3] ? '%' : '';
                   $this->result.= $arrMid[4];
                   $this->result.= '%' == $arrMid[5] ? '%' : '';
                   return$this->context;
         }
}
//5.工厂类
class InterpreterFactory{
         private$arrInters;
         private$context;
         privatestatic $ins;
         privatefunction __construct(){}
         privatefunction __clone(){}
         publicstatic function getInstance(){
                   if(null== self::$ins){
                            self::$ins= new self;
                            $this->arrInters= array();
                            $this->context= null;
                   }
                   returnself::$ins;
         }
         publicfunction setContext(Context $context){
                   $this->context= $context;
                   return$this;
         }
         publicfunction doInterpreter(){
                   $rawStr= $this->context->getRaw();
                   //原生的是where|and|compare|a|equal|b形式
                   $rawArr= explode('|', $rawStr);
                   if('where'!= $rawArr[0] || 6 != count($rawArr)){
                            return$this->setFalse('##error:wrong raw string##');
                   }
                   $this->context->setArrMid($rawArr);//设置中间变量
                   $interpreterType= $rawArr[2];//compare like
                   switch($interpreterType) {
                            case'compare':
                                     if(!isset($this->arrInters['compare'])){
                                               $this->arrInters['compare']= new InterpreterCompare($this->context);
                                     }
                                     $this->context= $this->arrInters['compare']->explain();
                                     break;
                            case'like':
                                     if(!isset($this->arrInters['like'])){
                                               $this->arrInters['like']= new InterpreterLike($this->context);
                                     }
                                     $this->context= $this->arrInters['like']->explain();                           
                                     break;
                            default:
                                     $this->setFalse('##error:wronginterpreter type##');
                                     break;
                   }
                   return$this->context;
         }
         privatefunction setFalse($interStr){
                   $this->context->setInter($interStr);
                   return$this->context;
         }
}
//6.客户端
$rawStr = 'where|and|compare|a|equal|b';
$rawContext = new Context($rawStr);
$interContext =InterpreterFactory::getInstance()
                ->setContext($rawContext)
                ->doInterpreter();

——written by linhxx 2017.08.31

相关阅读:

设计模式专题(二十二) ——享元模式

设计模式专题(二十一) ——中介者模式

设计模式专题(二十) ——职责链模式

设计模式专题(十九) ——命令模式

设计模式专题(十八) ——桥接模式

设计模式专题(十七) ——单例模式

设计模式专题(十六)——迭代器模式

设计模式专题(十五) ——组合模式

设计模式专题(十四)——适配器模式

设计模式专题(十三) ——备忘录模式

设计模式专题(十二)——状态模式

设计模式专题(十一)——抽象工厂模式

设计模式专题(十)——观察者模式

设计模式专题(九) ——外观模式

设计模式专题(八) ——模板方法模式

设计模式专题(七)——建造者模式

设计模式专题(六)——原型模式

设计模式专题(五)——工厂方法模式

设计模式专题(四)——代理模式

设计模式专题(三)——装饰模式

设计模式专题(二)——策略模式

设计模式专题(一)——面向对象的设计原则

本文分享自微信公众号 - 决胜机器学习(phpthinker),作者:linhxx

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2017-08-31

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 设计模式专题(二十四) ——访问者模式

    设计模式专题(二十四)——访问者模式 (原创内容,转载请注明来源,谢谢) 一、概述 访问者模式(visitor)表示一个作用于某对象结构中的各元素的操作,它使...

    用户1327360
  • PHP开发过程的那些坑(一) ——对象拷贝

    PHP开发过程的那些坑(一)——对象拷贝 (原创内容,转载请注明来源,谢谢) 坑: 做单元测试的过程中,想要运用@dataProvider方式分别传两个不同的对...

    用户1327360
  • 设计模式专题(九) ——外观模式

    设计模式专题(九) ——外观模式 (原创内容,转载请注明来源,谢谢) 一、概述 外观模式(Facade),为子系统中的一组接口提供一个一致的界面,此模式定义了...

    用户1327360
  • Vue+Echarts实现一个饼状图

    在jQuery里面,实现一个折线图,【前端统计图】echarts实现单条折线图 https://www.jianshu.com/p/0354a4f8c563。

    王小婷
  • 手写防抖函数 debounce 和节流函数 throttle

    一脸懵逼,真的是。这两个英文单词都是什么鬼(原谅我英文词汇量太烂),后来看了下,原来是防抖和节流的意思啊。

    请叫我大苏
  • ES6基础-ES6 class

    面向对象,即万物皆对象,面向对象是我们做开发一种的方式,开发思维,面向对象的思维中万物皆对象,以人作为例子,它的特性有哪些。比如有姓名,性别,出生年月,身高等,...

    达达前端
  • Element Tabs 标签页 展示Echart 并随窗口变化自适应

    1、如何在一个div中展示不同的图表  (点击tab时为Chart组件赋值,并传给子组件,子组件监听数据变化并在 $nextTick 中重新绘制表格)

    tianyawhl
  • 秒懂——惹人烦恼的this指向

      This是什么?什么是this指针?this指针指向哪里?何时使用this? useornotuse,thatisa question.  其中至关重要的 ...

    流眸
  • vue项目使用 富文本 封装

    我又来了,今天给大家分享一个富文本框的封装,写后台管理也离不开富文本框,我就做了封装,供大家参考,

    前端小白@阿强
  • PHP高级编程之消息队列

    PHP高级编程之消息队列 摘要 2015-10-19 第一版 2016-11-31 第二版 目录 1. 什么是消息队列 2. 为什么使用消息队列 3. 什么场合...

    netkiller old

扫码关注云+社区

领取腾讯云代金券