续 第一部分
消息(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包
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: }