一、问题产生背景

有一句话“小明和小龙是好朋友”,我想分析其中谁是人,我想分析他们的关系等多种需求,那么我们应该如何处理,如果为每一个关系都进行判断?显然不合适,我们可以将二者的关系进行抽象处理,然后就是实现多种关系规则,最后由规则解释你输入的话。解释器模式(Interpreter Pattern)提供了评估语言的语法或表达式的方式,它属于行为型模式。这种模式实现了一个表达式接口,该接口解释一个特定的上下文。这种模式被用在 SQL 解析、符号处理引擎等。如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题。

二、通常做法

AbstractExpression声明一个为抽象语法树中所有节点所共享的解释接口。

TerminalExpression表示终结符表达式,实现文法中终结符相关联的所有解释操作。

NonterminalExpression表示非终结符表达式,实现文法中所有非终结符的解释操作。

Context包含解释器外的一些全局信息。

Client构建语法树并调用解释器。

三、实例

1、构建一个抽象表达

namespace InterpreterPattern
{
public interface IExpress
{
bool Interpret(string context);
}
}

2、构建终结语法

namespace InterpreterPattern
{
public class TerminalExpress:IExpress
{
private string _data;
public TerminalExpress(string data)
{
_data = data;
} public bool Interpret(string context)
{
if (context.Contains(_data))
{
return true;
}
return false;
}
}
}

3、构建“与”语法

namespace InterpreterPattern
{
public class AndExpression : IExpress
{
private IExpress _expr1 = null;
private IExpress _expr2 = null; public AndExpression(IExpress expr1, IExpress expr2)
{
_expr1 = expr1;
_expr2 = expr2;
} public bool Interpret(string context)
{
return _expr1.Interpret(context) && _expr1.Interpret(context);
}
}
}

4、构建“或

namespace InterpreterPattern
{
public class OrExpression: IExpress
{
private IExpress _expr1 = null;
private IExpress _expr2 = null; public OrExpression(IExpress expr1, IExpress expr2)
{
_expr1 = expr1;
_expr2 = expr2;
} public bool Interpret(string context)
{
return _expr1.Interpret(context) || _expr1.Interpret(context);
}
}
}

5、构建解释器

namespace InterpreterPattern
{
public static class Translator
{
//规则:Robert 和 John 是男性
public static IExpress GetMaleExpression()
{
IExpress robert = new TerminalExpress("Robert");
IExpress john = new TerminalExpress("John");
return new OrExpression(robert, john);
} //规则:Julie 是一个已婚的女性
public static IExpress GetMarriedWomanExpression()
{
IExpress julie = new TerminalExpress("Julie");
IExpress married = new TerminalExpress("Married");
return new AndExpression(julie, married);
} }
}

6、客户端调用

namespace InterpreterPattern
{
class Program
{
static void Main(string[] args)
{
IExpress isMale = Translator.GetMaleExpression();
IExpress isMarriedWoman = Translator.GetMarriedWomanExpression(); Console.WriteLine("John is male? " + isMale.Interpret("John"));
Console.WriteLine("Julie is a married women? "+ isMarriedWoman.Interpret("Married Julie")); Console.ReadKey();
}
}
}

四、设计模式分析

优点: 1、可扩展性比较好,灵活。

2、增加了新的解释表达式的方式。

3、易于实现简单文法。

缺点: 1、可利用场景比较少。

2、对于复杂的文法比较难维护。

3、解释器模式会引起类膨胀。

4、解释器模式采用递归调用方法。

点击获取代码

设计模式のInterpreter Patern(解释器模式)----行为模式的更多相关文章

  1. 【GOF23设计模式】解释器模式 & 访问者模式

    来源:http://www.bjsxt.com/ 一.[GOF23设计模式]_解释器模式.访问者模式.数学表达式动态解析库式 1.解释器模式Interpreter  2.访问者模式Visitor 

  2. [JAVA设计模式]第四部分:行为模式

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  3. Java设计模式(14)责任链模式(Chain of Responsibility模式)

    Chain of Responsibility定义:Chain of Responsibility(CoR) 是用一系列类(classes)试图处理一个请求request,这些类之间是一个松散的耦合, ...

  4. Java经典设计模式之十一种行为型模式(附实例和详解)

    Java经典设计模式共有21中,分为三大类:创建型模式(5种).结构型模式(7种)和行为型模式(11种). 本文主要讲行为型模式,创建型模式和结构型模式可以看博主的另外两篇文章:Java经典设计模式之 ...

  5. Java设计模式之十一种行为型模式(附实例和详解)

    Java经典设计模式共有21中,分为三大类:创建型模式(5种).结构型模式(7种)和行为型模式(11种). 本文主要讲行为型模式,创建型模式和结构型模式可以看博主的另外两篇文章:J设计模式之五大创建型 ...

  6. Java经典设计模式之十一种行为型模式

    转载: Java经典设计模式之十一种行为型模式 Java经典设计模式共有21中,分为三大类:创建型模式(5种).结构型模式(7种)和行为型模式(11种). 本文主要讲行为型模式,创建型模式和结构型模式 ...

  7. Java设计模式(三) 抽象工厂模式

    原创文章,同步发自作者个人博客,转载请注明出处 http://www.jasongj.com/design_pattern/abstract_factory/ 抽象工厂模式解决的问题 上文<工厂 ...

  8. Java设计模式(十二) 策略模式

    原创文章,同步发自作者个人博客,http://www.jasongj.com/design_pattern/strategy/ 策略模式介绍 策略模式定义 策略模式(Strategy Pattern) ...

  9. Java设计模式(二) 工厂方法模式

    本文介绍了工厂方法模式的概念,优缺点,实现方式,UML类图,并介绍了工厂方法(未)遵循的OOP原则 原创文章.同步自作者个人博客 http://www.jasongj.com/design_patte ...

随机推荐

  1. TeamViewer 12\13\14 破解版(解决检测为商业用途的方式)

    一.Windows系统下破解TeamViewer的方式 1.用Windows直接卸载本地的TeamViewer软件2.下载一个Everything软件,并安装好它(这是一个搜索本机文件的工具,超级好用 ...

  2. js实现带上传进度的文件上传

    //获取文件筐的文件集合 var files = document.getElementById("file1").files; //创建FormData对象 相当于参数集合 存储 ...

  3. vsCode 列选择、列选中、选中列、选中多列(转载)

    VSCode列选择快捷键 来源 https://blog.csdn.net/Luyanc/article/details/80502069 VSCode列选择快捷键:Alt+Shift+左键 来一张效 ...

  4. springMVC_04controller四种配置总结

    一.通过url对应bean,加粗部分为必须有的 <bean class=" org.springframework.web.servlet.handler.BeanNameUrlHan ...

  5. 6.4 group by 优化

    1.小总结 group by 实质是先排序后进行分组,遵照索引建的最佳左前缀. 当无法使用索引列,增大max_length_for_sort_data参数的设置 + 增大sort_buffer_siz ...

  6. awk、nawk、mawk、gawk的简答介绍

    awk 是一种编程语言,用于在linux/unix下对文本和数据进行处理.数据可以来自标准输入.一个或多个文件,或其它命令的输出(即管道).它支持用户自定义函数和 动态正则表达式等先进功能,是linu ...

  7. thinkphp3.2模块名如何不区分大小写?

    thinkphp3.2中已配置:'URL_CASE_INSENSITIVE' => true,对于控制器及操作名大小写都可以,但仍对于模块名的大小写就运行机制出错,比如:http://www.x ...

  8. [转载]Web Service到底是什么

    转自:http://blog.csdn.net/wooshn/article/details/8069087/  武僧的专栏 一.序言 大家或多或少都听过WebService(Web服务),有一段时间 ...

  9. Web前端开发必备

    前端学习相关书籍 关于书籍 HTML.CSS 类别书籍,都是大同小异,在当当网.卓越网搜索一下很多推荐.如果感觉学的差不多了,可以关注一下<CSS禅意花园>,这个很有影响力. Javasc ...

  10. android网页打印,安卓网页打印,h5页面打印,浏览器打印,js打印工具

    Android设备打印比较麻烦,一般设备厂商都提供原生app开发的SDK,我们web开发者为难了,不会原生开发啊 给大家提供一个思路,实现web加壳,利用打印浏览器实现 简单来说就是把我们的web页面 ...