JAVA SCRIPT设计模式是本人根据GOF的设计模式写的博客记录。使用JAVA SCRIPT语言来实现主体功能,所以不可能像C++,JAVA等面向对象语言一样严谨,大部分程序都附上了JAVA SCRIPT代码,代码只是实现了设计模式的主体功能,不代表全部的正确,特此声明。若读者需要了解设计模式目录、原则、设计变化方向,环境相关等信息请查看设计模式开篇。
参与者:
给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
如果一种特定类型的问题发生的频率足够高 , 那么可能就值得将该问题的各个实例表述为 一个简单语言中的句子(then it might beworthwhile to express instances of the problem as sentences in a simple language)。这样就可以构建一个解释器 , 该解释器通过解释这些句子来解决该问题。
例如,搜索匹配一个模式的字符串是一个常见问题。正则表达式是描述字符串模式的一 种标准语言。与其为每一个的模式都构造一个特定的算法,不如使用一种通用的搜索算法来解释执行一个正则表达式,该正则表达式定义了待匹配字符串的集合。 解释器模式描述了如何为简单的语言定义一个文法 , 如何在该语言中表示一个句子 , 以及如何解释这些句子。
考虑以下文法定义正则表达式 :
expression ::= literal | alternation | sequence | repetition |
'(' expression ')'
alternation ::= expression '|' expression
sequence ::= expression '&' expression
repetition ::= expression '*'
literal ::= 'a' | 'b' | 'c' | ... { 'a' | 'b' | 'c' | ... }*
符号expression是开始符号,literal是定义简单字的终结符。
解释器模式使用类来表示每一条文法规则。在规则右边的符号是这些类的实例变量。上面的文法用五个类表示:一个抽象类RegularExpression和它四个子类LiteralExpression(文字)、AlternationExpression(选择or)、SequenceExpression(sequ 跟随)和RepetitionExpression(重复)后三个类定义的变量代表子表达式。
每个用这个文法定义的正则表达式都被表示为一个由这些类的实例构成的抽象语法树。例如,抽象语法树:
表示正则表达式:
raining&(dogs|cats)*
如果我们为RegularExpression的每一子类都定义解释(Interpret)操作,那么就得到了为这些正则表达式的一个解释器。解释器将该表达式的上下文做为一个参数。上下文包含输入字符串和关于目前它已有多少已经被匹配等信息。为匹配输入字符串的下一部分,每一RegularExpression的子类都在当前上下文的基础上实现解释操作(Interpret)。例如
等等。
下面是Interpreter所要考虑的一些特殊问题:
目录结构:
export default class RegularExpression {constructor( ) {}/*解释context :contains information that's global to the interpreter. *//*** 实现了该正则表达式的一个解释器。定义抽象语法树的每一个类都实现了这一操作。inputString 读入的部分输入字符串,返回object*/Match(context){}}
import RegularExpression from '../RegularExpression.js'; export default class LiteralExpression extends RegularExpression {#components;constructor(components ) {super();this.#components=components;}/*解释*/Match(context){let inputString=context.GetInString();let arrayString=inputString.split(' ');//根据空格 获取tokenlet sIndex=0;for(let n=0;n
import RegularExpression from '../RegularExpression.js'; export default class AlternationExpression extends RegularExpression {#altercative1;#altercative2;constructor( altercative1,altercative2 ) {super();this.#altercative1=altercative1;this.#altercative2=altercative2;}/*解释*/Match(context){if(this.#altercative1.Match(context)){return true;}else{if(this.#altercative2.Match(context))return true;else{return false;}}}}
import RegularExpression from '../RegularExpression.js';export default class RepetitionExpression extends RegularExpression {#repetition;constructor(repetition) {super();this.#repetition = repetition;}/*解释*/Match(context) {let bOnceFind = false;do {if (this.#repetition.Match(context)) {bOnceFind = true;} else {//没有匹配到break;}} while (true);if(!bOnceFind) context.SetMatchStringNull();return bOnceFind; }
}
import RegularExpression from '../RegularExpression.js'; export default class SequenceExpression extends RegularExpression {#expression1;#expression2;constructor( expression1,expression2 ) {super();this.#expression1=expression1;this.#expression2=expression2;}/*解释*/Match(context){if(this.#expression1.Match(context)){if(this.#expression2.Match(context))return true;else{//没有匹配到context.SetMatchStringNull();return false}}elsecontext.SetMatchStringNull();return false}}
import AlternationExpression from './Expression/impl/AlternationExpression.js';
import LiteralExpression from './Expression/impl/LiteralExpression.js';
import RepetitionExpression from './Expression/impl/RepetitionExpression.js';
import SequenceExpression from './Expression/impl/SequenceExpression.js';
import Context from './Expression/Context.js';export default class Client {constructor(ctx, zooRect) {/*** 构建语法树*/let aLiteralExpression = new LiteralExpression('raining');let aLiteralExpressiondogs = new LiteralExpression('dogs');let aLiteralExpressioncats = new LiteralExpression('cats');let anAlternationExpression = new AlternationExpression(aLiteralExpressiondogs, aLiteralExpressioncats);let aRepetitionExpression = new RepetitionExpression(anAlternationExpression);let aSequenceExpression = new SequenceExpression(aLiteralExpression, aRepetitionExpression);/*** 匹配字符串*/let aString = 'raining cats dogs dogs cat';let context=new Context(aString);console.log(` 原始字符串 `+aString +'匹配表达式 raining&(dogs|cats)*');aSequenceExpression.Match(context);console.log(` 匹配的字符串 `+context.GetMatchString());let bString = 'raining cats dog dogs cat';let bcontext=new Context(bString);console.log(` 原始字符串 `+bString +'匹配表达式 raining&(dogs|cats)*');aSequenceExpression.Match(bcontext);console.log(` 匹配的字符串 `+bcontext.GetMatchString());let cString = 'raining cat dogs dog cat';let ccontext=new Context(cString);console.log(` 原始字符串 `+cString +'匹配表达式 raining&(dogs|cats)*');aSequenceExpression.Match(ccontext);console.log(` 匹配的字符串 `+ccontext.GetMatchString());}}
测试结果:
Client.js:27 原始字符串 raining cats dogs dogs cat匹配表达式 raining&(dogs|cats)*
Client.js:29 匹配的字符串 raining cats dogs dogs
Client.js:33 原始字符串 raining cats dog dogs cat匹配表达式 raining&(dogs|cats)*
Client.js:35 匹配的字符串 raining cats
Client.js:40 原始字符串 raining cat dogs dog cat匹配表达式 raining&(dogs|cats)*
Client.js:42 匹配的字符串
下载链接:https://pan.baidu.com/s/1XuPqp84cccBNVkbnMY3sKw
提取码:q2ut