3 类的设计
根据上面的规定,显然我们需要两个类:Client和ChatRoom。在开发过程早期阶段,对于仿真来说无需用户干预,我们明确地按照随机过程对用户行为(连接请求和聊天信息)进行建模。以后,客户模型将会被与软件打交道的真实客户所代替。仿真开始时,会初始化五个Client实例和两个ChatRoom实例。
我们还加入了一个singleton类:Manager。Manager以仲裁者的身份中继组件之间的所有通信。这种中央控制措施将会帮助截取系统传递的所有消息,使用它们就可以检查模型的正确性。
图一描述了由这三个类组成的UML类图。
ChatRoom提供两个方法处理到达的事件。request处理来到的请求,每个请求都有参数clientID和roomID。ChatRoom把接收或拒绝通知发回拥有全局ID标识clientID的发送者。它也使用参数roomID来决定请求是发给它自己还是发给另外一个聊天室了1。send方法接收由客户clientID发送的消息msg。这条msg将会在一秒钟之后被广播出去。
Client的方法accept和reject处理到达的接收和拒绝通知。参数clientID用来确定目标客户。当一个Client接收到一个broadcast事件,它会检查自己是否在clients集合中。如果情况确实如此,消息msg就会在输出中被打印出来。
Manager中继连接请求、接收和拒绝通知、来自客户的消息以及聊天室的广播。例如,如果它收到来自聊天室的广播,有三个参数会告诉它消息最初的发送者(客户),广播者(聊天室)以及消息字符串。然后它把消息发给所有连接在聊天室中的,除了最初发送者以外的客户。
尽管这种API定义不是形式化的,但接口背后的行为还是很容易理解的。但是,检查协议的一致性会有些困难,甚至是不可能的,原因如下:
行为隐藏在接口背后,它只能在理解的基础上进行解释。
协议是用自然语言表达的,程序不可能很容易地处理。
对于一个定义完好的系统来说,会有许多接口设计。它们可能有相当大的不同。例如,本设计中用Manager类来拦截通信。另一项设计可能会使用RequestManager来拦截请求、接收和拒绝,用MessageManager来拦截消息和发送广播。更有另外一种设计可能根本就不会使用任何管理器。