前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >设计模式专题(二十三) ——解释器模式

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

作者头像
用户1327360
发布2018-03-07 11:56:15
6820
发布2018-03-07 11:56:15
举报
文章被收录于专栏:决胜机器学习

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

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

一、概述

解释器模式(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、具体实现

代码语言:javascript
复制
<?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

相关阅读:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2017-08-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 决胜机器学习 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 设计模式专题(二十二) ——享元模式
  • 设计模式专题(二十一) ——中介者模式
  • 设计模式专题(二十) ——职责链模式
  • 设计模式专题(十九) ——命令模式
  • 设计模式专题(十八) ——桥接模式
  • 设计模式专题(十七) ——单例模式
  • 设计模式专题(十六)——迭代器模式
  • 设计模式专题(十五) ——组合模式
  • 设计模式专题(十四)——适配器模式
  • 设计模式专题(十三) ——备忘录模式
  • 设计模式专题(十二)——状态模式
  • 设计模式专题(十一)——抽象工厂模式
  • 设计模式专题(十)——观察者模式
  • 设计模式专题(九) ——外观模式
  • 设计模式专题(八) ——模板方法模式
  • 设计模式专题(七)——建造者模式
  • 设计模式专题(六)——原型模式
  • 设计模式专题(五)——工厂方法模式
  • 设计模式专题(四)——代理模式
  • 设计模式专题(三)——装饰模式
  • 设计模式专题(二)——策略模式
  • 设计模式专题(一)——面向对象的设计原则
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档