第一部分

消息(Messages)

翻译源程序时,Parser需要汇报一些状态信息,比如发现语法错误后的错误消息。不过你不能让paser关心该在那儿发送消息或者消息收到之后该怎么处理。类似地,source(类)组件每读入一行时可发送一条包含行文本和行号的消息。接收者可能用这些消息产生一个源码清单,但是你不能让source组件操心这事。

设计笔记

保持消息的发送者(parser和source)与消息接收者之间松耦合。两个组件松耦合就是说他们之间的依赖最小,一个组件能够很容易在不对另一组件造成不利影响下更改。在大型复杂应用中,松耦合能让独立组件开发与团队并行组件开发和谐相处。

图2-4 针对图2-3 进行了扩展,展示了Parser和Source类要用到的message包中的消息接口和类,这两个类都实现了接口MessageProducer且每个都有一个MessageHandler。两个类也引用了Message和MessageType类。

设计笔记

在UML类图中,一个带封闭空箭头的虚箭号(比如Parser到MessageProducer和Source到MessageProducer)指出了一个类实现的接口。

图2-4 message包

(基于Java)编写编译器和解释器-第2章:框架I:编译器和解释器-第二部分(连载)

Parser和Source类都实现了MessageProducer接口,因此每个类必须定义addMessageListener(),removeMessageListener()和sendMessage()方法。与此同时,任何想接收parser和source消息的对象可以分别通过调用parser或source的addMessageListener方法去订阅这些消息。对象不想监听的时候可调用removeMessageListener方法。parser或source每个都能有多个监听器,当它有消息时,可通过调用每一个监听器的messageReceived方法将消息发送出去。

消息生产者(这儿是典型的生产者1/消费者N模式)可拥有一个MessageHandler对象,这样生产者就在addMessageListener()、removeMessageListener()和sendMessage()等方法中调用相应MessageHandler中的方法。换句话说,消息生产者将这些方法交由消息句柄类(MessageHandler)代理。

每次source读了一行新的源代码,在readLine()方法送就会调用消息句柄类的sendMessage()方法,将包含行数和行类容的SOURCE_LINE消息发送到所有监听器。SOURCE_LINE消息报文(body字段)有两个域,一个是lineNumber表示行号,一个是lineText表示行文本。(实际上以数组表示的

清单2-7 展示了MessageProducer接口

/**
 * <p>能够产生消息的类的公共接口,source, scanner, parser, backend都能产生消息</p>
 */
interface MessageProducer
   5: {
/**
     * @param listener 要加入的监听器
     */
void addMessageListener(MessageListener listener);
  10:  
/**
     * @param listener 要移除的监听器
     */
void removeMessageListener(MessageListener listener);
  15:  
/**
     * @param message 要向所有注册的监听器广播的消息
     */
void sendMessage(Message message);
  20: }

相关文章:

  • 2021-12-07
  • 2021-07-28
  • 2021-09-08
  • 2021-08-05
  • 2021-07-05
  • 2021-11-20
  • 2022-01-13
  • 2021-11-20
猜你喜欢
  • 2021-08-13
  • 2021-07-25
  • 2022-02-21
  • 2021-11-27
  • 2021-12-31
  • 2021-12-10
  • 2022-01-14
相关资源
相似解决方案