设计模式-命令、解释器

96 阅读4分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

一、命令模式

定义: 将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。这样两者之间通过命令对象进行沟通,这样方便将命令对象进行储存、传递、调用、增加与管理。

理解: 命令模式将请求一对象的形式包装,传递给调用对象,调用对象再传递给具体的对象去执行命令。命令模式包含4个角色,抽象命令角色声明执行命令的接口,抽象方法;具体命令角色是抽象命令角色的具体实现,通过调用接收者的功能来完成命令要执行的操作;接受者角色执行命令的相关操作,是命令的真正执行者;请求者角色是请求的发送者,拥有很多命令对象,访问命令对象来执行请求。例如我们去饭店吃饭,首先服务员拿菜单给我们点菜,点完以后服务员就交给能做这个菜的厨师去做,我们不用与厨师直接交互,我们需要什么,只用在菜单上点,这里我们相当于请求者,菜单是抽象命令角色,服务员是具体命令类,厨师就是接受者执行真正的命令。命令模式可以支持撤销,实现一个撤销的方法,返回执行前的状态。宏命令模式就是将命令模式与其他模式相结合,宏命令模式包含一组命令,执行的时候它会执行所包含的所有命令。

优点: 降低系统耦合度,使调用者角色与接收者角色之间解耦;扩展性好,增加删除命令很方便,符合开闭原则;

缺点: 增加的系统的复杂性,因为每一个具体操作都需要设计一个具体命令类,产生了大量的命令类;

场景: 请求调用者与请求接收者需要解耦;需要经常增加、删除命令时;需要执行一组操作时可以使用宏命令;需要支持命令的撤销和恢复。

二、解释器模式

定义: 给分析对象定义一个语言,并定义该语言的文法表示,再设计一个解析器来解释语言中的句子。也就是说,用编译语言的方式来分析应用中的实例。这种模式实现了文法表达式处理的接口,该接口解释一个特定的上下文。

理解: 开发过程中,如果有重复出现或者相识的问题可以将他们归纳成一种语言,这些问题的实例就是语言中的句子,可以用解释器模式来实现。“文法”指语言的语法规则,“句子”是语言集中的元素。解释器模式主要包含5个角色,抽象表达式角色定义解释器的接口,声明解释器的解释操作;终结符表达式角色是抽象表达式的子类,实现文法中与终结符相关的解释操作,文法中的每一个终结符都有一个具体终结表达式与之相对应;非终结符表达式角色也是抽象表达式的子类,用来实现文法中与非终结符相关的解释操作,文法中的每条规则都对应于一个非终结符表达式;环境角色通常包含各个解释器需要的数据或是公共的功能,一般用来传递被所有解释器共享的数据,后面的解释器可以从这里获取这些值;客户端主要任务是将需要分析的句子或表达式转换成使用解释器对象描述的抽象语法树,然后调用解释器的解释方法,当然也可以通过环境角色间接访问解释器的解释方法。

优点: 扩展性好,可以通过继承等机制来改变或扩展解释器的文法;语法树中的节点都是相似的,使用比较容易实现。

缺点: 执行效率低,因为解释器中使用了大量的循环递归,当解释的句子比较复杂时,执行效率就会非常低;系统复杂度高,解释器中每个规则至少要定义一个类,如果规则很多时,那就需要定义很多类,提供了系统复杂性;应用比较少,一般很少使用。

场景: 当问题重复出现或者相似度比较高时;语言文发简单,不考虑效率性能问题时;