中介者模式与解释器模式(2)

简介: 中介者模式与解释器模式(2)

三、中介者模式在源码中的应用

首先来看JDK中的Timer类 ,打开Timer的结构我们发现Timer类中有很多的schedule() 重载方法,如下图:


image.png


我们任意点开其中一个方法,发现所有方法最终都是调用了私有的sched()方法,我们来看 —下它的源码: ::


 public class Timer {
     public void schedule(TimerTask task, long delay, long period) {
         if (delay < 0)
             throw new IllegalArgumentException("Negative delay.");
         if (period <= 0)
             throw new IllegalArgumentException("Non-positive period.");
         sched(task, System.currentTimeMillis()+delay, -period);
     }
     private void sched(TimerTask task, long time, long period) {
         if (time < 0)
             throw new IllegalArgumentException("Illegal execution time.");
         // Constrain value of period sufficiently to prevent numeric
         // overflow while still being effectively infinitely large.
         if (Math.abs(period) > (Long.MAX_VALUE >> 1))
             period >>= 1;
         synchronized(queue) {
             if (!thread.newTasksMayBeScheduled)
                 throw new IllegalStateException("Timer already cancelled.");
             synchronized(task.lock) {
                 if (task.state != TimerTask.VIRGIN)
                     throw new IllegalStateException(
                         "Task already scheduled or cancelled");
                 task.nextExecutionTime = time;
                 task.period = period;
                 task.state = TimerTask.SCHEDULED;
             }
             queue.add(task);
             if (queue.getMin() == task)
                 queue.notify();
         }
     }
 }    


而且,我们发现,不管是什么样的任务都被加入到一个队列中顺序执行。我们把这个队列中 的所有对象称之为"同事”。同事之间通信都是通过Timer来协调完成的,Timer就承担了中 介者的角色。


四、解释器模式

解释器模式(Interpreter Pattern) 是指给定一门语言, 定义它的语法的一种表示, 并定义一个解释器,该解释器使用该表示来解释语言中的句子。是一种按照规定的语法进行解析的模式,属于行为型模式。


就比如编译器可以将源码编译解释为机器码, 让CPU能进行识别并运行。解释器模式的作用其实与编译器一样,都是将一些固定的语法进行解释,构建出一个解释句子的解释器。简单理解,解释器是一个简单语法分析工具,它可以识别句子语义,分离终结符号和非


终结符号,提取出需要的信息,让我们能针对不同的信息做出相应的处理。其核心思想是识别语法,构建解释。


解释器模式的应用场景:


其实我们每天都生活在解释器模式中,我们平时所听到的音乐都可以通过简谱记录下来;还有战争年代发明的摩尔斯电码(又译为摩斯密码, Morsecode) , 其实也是一种解释器。我们的程序中,如果存在一种特定类型的问题,该类型问题涉及多个不同实例,但是具备固定语法描述,那么可以使用解释器模式对该类型问题进行解释,分离出需要的信息,根据获取的信息做出相应的处理。简而言之,对于一些固定语法构建一个解释句子的解释器。解释器模式适用于以下应用场景:


一些重复出现的问题可以用一种简单的语言来进行表达;


一个简单语法需要解释的场景。


解释器模式主要包含四种角色:



1.抽象表达式(Expression) :负责定义一个解释方法interpret, 交由具体子类进行具体解释;


2.终结符表达式(Terminal Expression) :实现文法中与终结符有关的解释操作。文法中的每一个终结符都有一个具体终结表达式与之相对应,比如公式R=R1+R2,R1和R2就是终结符,对应的解析R1和R2的解释器就是终结符表达式。通常一个解释器模式中只有一个终结符表达式,但有多个实例,对应不同的终结符(R1,R2);


3.非终结符表达式(Nonterminal Expression) :实现文法中与非终结符有关的解释操作。文法中的每条规则都对应于一个非终结符表达式。非终结符表达式一般是文法中的运算符或者其他关键字,比如公式R=R1+R2中, “+”就是非终结符,解析“+”的解释器就是一个非终结符表达式。非终结符表达式根据逻辑的复杂程度而增加,原则上每个文法规则都对应一个非终结符表达式;


4.上下文环境类(Context) :包含解释器之外的全局信息。它的任务一般是用来存放文法中各个终结符所对应的具体值,比如R=R1+R2,给R1赋值100,给R2赋值200,这些信息需要存放到环境中。


五、解释器模式的实例


下面我们用解释器模式来实现一个数学表达式计算器,包含加减乘除运算。首先定义抽象表达式角色IArithmeticInterpreter接口:



public interface IArithmeticInterpreter {
    int interpret();
}


创建终结表达式角色AbstractInterpreter抽象类:


public abstract class AbstractInterpreter implements IArithmeticInterpreter {
    protected IArithmeticInterpreter left;
    protected IArithmeticInterpreter right;
    public AbstractInterpreter(IArithmeticInterpreter left, IArithmeticInterpreter right) {
        this.left = left;
        this.right = right;
    }
}


分别创建非终结表达式角色加、减、乘、除解释器:


//加
public class AddInterpreter extends AbstractInterpreter {
    public AddInterpreter(IArithmeticInterpreter left, IArithmeticInterpreter right) {
        super(left, right);
    }
    public int interpret() {
        return this.left.interpret() + this.right.interpret();
    }
}
//减
public class SubInterpreter extends AbstractInterpreter {
    public SubInterpreter(IArithmeticInterpreter left, IArithmeticInterpreter right) {
        super(left, right);
    }
    public int interpret() {
        return this.left.interpret() - this.right.interpret();
    }
}
//乘
public class MultiInterpreter extends AbstractInterpreter {
    public MultiInterpreter(IArithmeticInterpreter left, IArithmeticInterpreter right){
        super(left,right);
    }
    public int interpret() {
        return this.left.interpret() * this.right.interpret();
    }
}
//除
public class DivInterpreter extends AbstractInterpreter {
    public DivInterpreter(IArithmeticInterpreter left, IArithmeticInterpreter right){
        super(left,right);
    }
    public int interpret() {
        return this.left.interpret() / this.right.interpret();
    }
}
目录
相关文章
|
架构师 NoSQL Java
【案例实战】SpringBoot3.x自定义封装starter实战
【案例实战】SpringBoot3.x自定义封装starter实战
【案例实战】SpringBoot3.x自定义封装starter实战
使用pip时报错:No module named ‘chardet‘ 的解决办法
使用pip时报错:No module named ‘chardet‘ 的解决办法
2424 0
使用pip时报错:No module named ‘chardet‘ 的解决办法
|
12月前
|
存储 SQL 前端开发
【若依RuoYi-Vue | 项目实战】帝可得后台管理系统(二)
接着上回的【若依RuoYi-Vue | 项目实战】基于若依的帝可得后台管理系统(一),本次我们继续完成人员管理、设备管理、策略管理模块的开发。
1892 6
【若依RuoYi-Vue | 项目实战】帝可得后台管理系统(二)
|
12月前
|
Java 数据库连接 Maven
最新版 | SpringBoot3如何自定义starter(面试常考)
在Spring Boot中,starter是一种特殊的依赖,帮助开发人员快速引入和配置特定功能模块。自定义starter可以封装一组特定功能的依赖和配置,简化项目中的功能引入。其主要优点包括模块化、简化配置、提高代码复用性和实现特定功能。常见的应用场景有短信发送模块、AOP日志切面、分布式ID生成等。通过创建autoconfigure和starter两个Maven工程,并编写自动配置类及必要的配置文件,可以实现一个自定义starter。最后在测试项目中验证其有效性。这种方式使开发者能够更便捷地管理和维护代码,提升开发效率。
1757 1
最新版 | SpringBoot3如何自定义starter(面试常考)
|
负载均衡 应用服务中间件 网络安全
Django后端架构开发:Nginx服务优化实践
Django后端架构开发:Nginx服务优化实践
259 2
|
存储 安全 测试技术
移动应用的安全测试与加固技术深度解析
【8月更文挑战第2天】随着移动互联网的发展,移动应用成为生活必需,但安全威胁也随之加剧。本文深入探讨移动应用的安全测试与加固技术,包括权限访问、数据加密、安全协议、组件安全测试及渗透测试等内容,同时覆盖源代码、运行时环境、数据传输存储及业务逻辑加固等方面,为开发者提供全面指导,以保护用户数据和企业资产安全。
674 12
|
存储 Java 程序员
Java 毕业设计,基于 SpringBoot 的前后端分离的高校招生管理系统(一)
Java 毕业设计,基于 SpringBoot 的前后端分离的高校招生管理系统
|
前端开发 小程序 Java
【规范】SpringBoot接口返回结果及异常统一处理,这样封装才优雅
本文详细介绍了如何在SpringBoot项目中统一处理接口返回结果及全局异常。首先,通过封装`ResponseResult`类,实现了接口返回结果的规范化,包括状态码、状态信息、返回信息和数据等字段,提供了多种成功和失败的返回方法。其次,利用`@RestControllerAdvice`和`@ExceptionHandler`注解配置全局异常处理,捕获并友好地处理各种异常信息。
6769 1
【规范】SpringBoot接口返回结果及异常统一处理,这样封装才优雅
|
机器学习/深度学习 人工智能 自然语言处理
【机器学习】GLM4-9B-Chat大模型/GLM-4V-9B多模态大模型概述、原理及推理实战
【机器学习】GLM4-9B-Chat大模型/GLM-4V-9B多模态大模型概述、原理及推理实战
1791 0
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的城市公交查询系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的城市公交查询系统附带文章源码部署视频讲解等
112 0