行为型模式之解释器模式 太过爱你忘了你带给我的痛 2024-04-17 13:53 20阅读 0赞 @[TOC][] > 解释器模式(Interpreter Pattern)提供了评估语言的语法或表达式的方式,它属于行为型模式.这种模式实现了一个表达式接口,该接口解释一个特定的上下文. 这种模式被用在 SQL 解析、符号处理引擎等。 # 模式结构和说明 # 解释器模式主要包括以下几个角色: **AbstractExpression**:抽象表达式.声明一个抽象的解释操作,该接口为抽象语法树种所有的节点共享 **TerminalExpression**:终结符表达式.实现与文法中的终结符相关的解释操作.实现抽象表达式中所要求的方法.文法中每一个终结符都有一个具体的终结表达式与之相对应 **NonterminalExpression**:非终结符表达式。为文法中的非终结符相关的解释操作 **Context**:环境类.包含解释器之外的一些全局信息 抽象语法树描述了图和构成一个复杂的句子,通过对抽象语法树的分析,可以识别出语言中的终结符和非终结符.在解释器模式中由于每一种终结符表达式,非终结符表达式都会有一个具体的实例与之相对应,多以系统的扩展性比较好 # 示例代码 # 现在我们用解释器模式来实现一个基本的加、减、乘、除和求模运算。例如用户输入表达式“3 \* 4 / 2 % 4”,输出结果为2 1. 定义抽象表达式node @implementation Node - (int)interpret { return 0; } @end 复制代码 从上面的表达式可以,终结符有两种,一种是数字,另一个中是变量 2. 定义终结符表达式 @implementation ValueNode + (instancetype)valueNodeWithValue:(int)value { ValueNode *node = [[ValueNode alloc] init]; node.value = value; return node; } - (int)interpret { return self.value; } @end 复制代码 @implementation SymbolNode + (instancetype)symbolNodeWithLeft:(Node *)left right:(Node *)right { SymbolNode *node = [[[self class] alloc] init]; node.leftN = left; node.rightN = right; return node; } @end 复制代码 1. 定义非终结表达式 @implementation MulNode - (int)interpret { return self.leftN.interpret * self.rightN.interpret; } @end 复制代码 @implementation ModNode - (int)interpret { return self.leftN.interpret % self.rightN.interpret; } @end 复制代码 @implementation DivNode - (int)interpret { return self.leftN.interpret / self.rightN.interpret; } @end 复制代码 1. 客户端使用 Node *left = nil; Node *right = nil; NSMutableArray *nodeArr = [NSMutableArray array]; NSString *str = @"3 * 4 / 2"; NSArray *stateArr = [str componentsSeparatedByString:@" "]; for (int i = 0; i < stateArr.count; i++) { if ([stateArr[i] isEqualToString:@"*"]) { left = nodeArr.lastObject; int value = [stateArr[++i] intValue]; right = [ValueNode valueNodeWithValue:value]; [nodeArr addObject:[MulNode symbolNodeWithLeft:left right:right]]; } else if ([stateArr[i] isEqualToString:@"/"]){ left = nodeArr.lastObject; int value = [stateArr[++i] intValue]; right = [ValueNode valueNodeWithValue:value]; [nodeArr addObject:[DivNode symbolNodeWithLeft:left right:right]]; }else if ([stateArr[i] isEqualToString:@"%"]){ left = nodeArr.lastObject; int value = [stateArr[++i] intValue]; right = [ValueNode valueNodeWithValue:value]; [nodeArr addObject:[ModNode symbolNodeWithLeft:left right:right]]; } else { int value = [stateArr[i] intValue]; [nodeArr addObject:[ValueNode valueNodeWithValue:value]]; } } SymbolNode *node = nodeArr.lastObject; NSLog(@"最终的值为%d",[node interpret]); 复制代码 # 模式讲解 # ## 优点 ## 灵活的扩展性,想扩展语法规则时只需新增新的解释器就可以了。如上面的例子中,想增加乘除法,只想增加相应的解释类,并增加相应的表达式解释操作即可 ## 缺点 ## * 每一个文法都至少对应一个解释器,会产生大量的类,难于维护。 * 解释器模式由于大量使用循环和递归,需要考虑效率的问题,而且调试也不方便。 * 对于复杂的文法,构建其抽象语法树会显得异常繁琐。 * 所以不推荐在重要的模块中使用解释器模式,维护困难。 ## 总结 ## 解释器模式使用解释器对象来表示和处理相应的语法规则,一般一个解释器处理一条语法规则。理论上来说,只要能用解释器对象把符合语法的表达式表示出来,而且能够构成抽象的语法树,那都可以使用解释器模式来处理。 [Demo地址][Demo] 转载于:https://juejin.im/post/5d5fa94ff265da03bf0f4bcc [TOC]: https://link.juejin.im?target=%25E8%25A1%258C%25E4%25B8%25BA%25E5%259E%258B%25E6%25A8%25A1%25E5%25BC%258F%25E4%25B9%258B%25E8%25A7%25A3%25E9%2587%258A%25E5%2599%25A8%25E6%25A8%25A1%25E5%25BC%258F [Demo]: https://link.juejin.im?target=https%3A%2F%2Fgithub.com%2Fjiajianxing%2FDesignPatterns
还没有评论,来说两句吧...