APP下载

利用观察者模式实现自顶向下消息传递

2011-01-26肖永刚

文山学院学报 2011年6期
关键词:发布者观察者消息

肖永刚

(文山学院计科系,云南文山663000)

校园中存在着许多的对象,例如校园、教师、学生等,这些对象代表着真实校园中的各种实体。在真实的校园中消息是这样传递的,首先校园有了一个消息,它需要将这个消息通知教师,再由教师将这个消息通知学生。或者,教师有了一个消息,他需要将这个消息通知学生,但不必将这个消息通知校园。消息总是从较高的层次向较低的层次传递,不会反向的从较低的层次向较高的层次传递。这是一种自顶向下式的消息传递机制。

同样的,在设计虚拟校园[1]时,也要实现这样的一种消息传递方式。校园、教师和学生等对象构成了整个虚拟校园的基本元素。文章只介绍了这三者之间的消息传递机制,以简化需要讨论的问题。

观察者模式[2]在对象之间定义了一种一对多的依赖关系。当一个对象(发布者)的状态发生变化时,其它的对象(观察者),会马上感知或接受到这种变化,所以观察者模式在开发虚拟校园时非常有用。对比两种设计虚拟校园的方法,一种没有使用观察者模式,而只是基于组合原则来构建系统,另一种应用了观察者模式来设计开发虚拟校园,在校园、教师和学生三个对象之间建立起一对多的依赖关系。文章用对比的方式来说明应用观察者模式设计带来的好处[3]。

1 初始的设计

类图如图1所示,校园、教师和学生通过组合的方式联系在一起,组合原则广泛地应用于这个设计中。Campus类包含一个实体变量teachers,用来代表教师对象,即消息要传递给谁。Teacher类包含一个实体变量students,代表学生对象,即要继续将消息传递给谁。三个类之间通过变量teachers和变量students进行访问。

图1 应用组合方式构建的系统

序列图[4]如图2所示,系统生成参与消息传递的对象,分别属于 Campus、Teacher和 Student类。在对象内部已经指定了消息的发送者和接受者,在系统运行的过程中不会也不能更改它们。首先Campus类产生一个消息并将它传递给Teacher类,通过调用Campus类的broadcast方法实现。然后Teacher类接受这个消息并将它传递给Student类,通过调用Teacher类的 receiveMessage和 broadcast方法实现。最后Student类接受这个消息,通过调用Student类的receiveMessage方法实现。这样的方式可以实现消息的自顶向下的传递,满足系统设计的要求。

图2 应用组合方式时的序列图

但是这种设计方式有它的不足之处。一方面,当要扩展虚拟校园的功能时,比方说增加一些对象,这些对象同样要参与到消息传递的过程当中,此时就需要对已有类的定义代码进行修改,定义更多的实体变量来代表新加入的对象。当加入到系统中的对象越来越多时,这种修改的工作量将变得很大。产生错误的几率也随之增加,系统的可维护性变得很差。另一方面,这个设计中没有提供一种灵活的更改消息发送或接受对象的方法。在系统运行时,不能动态的将对象加入到消息传递过程中,或从消息传递过程中将对象移除,因为这些都是在类的定义中预先指定了的。通过这种方式设计的系统缺少灵活性。

2 改进的设计

应用观察者模式重新设计了虚拟校园,系统在可扩展性和灵活性上都获得很大的提高,类图如图3所示,Campus类是发布者;Teacher类有两个身份,既可以是发布者又可以是观察者,Student类只能作为观察者。当Campus类或者Teacher类发送消息时,它们相应的观察者将会收到消息。采用这样的设计方式,整个系统的灵活性得到了提高。只要一个对象实现了发布者接口,它就可以是发布者,不管这个对象实际上是做什么的[5]。同样,只要一个对象实现了观察者接口,它就可以是观察者。所以,当要扩展系统功能时,可以很方便地添加一些实现了这两种接口的类,而不需要对已有的类进行修改。唯一需要保证的是,这些类实现了相应的接口。

图3 应用观察者模式构建的系统

虚拟校园系统在校园、教师和学生之间建立了两个一对多的依赖关系。一个是Campus类与Teacher类,Teacher类依赖Campus类传递消息;另一个是Teacher类与 Student类,Student类依赖 Teacher类传递消息。Teacher类扮演了两种身份,既是消息的接受方又是消息的发送方。

在Subject接口中,方法attach用来注册观察者,detach用来注销观察者,方法notify用来通知观察者;在Observer接口中,方法receiveMessage用来接受消息。在Campus类中,变量observers用来代表消息的观察者列表,方法getMessage用来产生新的消息;在Teacher类中,变量observers用来代表消息的观察者列表,变量campus用来代表消息的发布者,方法getMessage用来产生新的消息;在Student类中,变量campus用来代表消息的发布者,方法get-Message用来产生新的消息。

序列图如图4所示,当Campus类传递消息之前,它需要调用attach和detach方法决定消息由谁接受。一旦产生一条消息,它首先将这条消息传递给Teacher类,Teacher类收到消息后,也需要调用attach和detach方法决定消息由谁接受,再将这条消息传递给Student类。这样,通过动态的注册和注销观察者,以及利用不同对象之间方法的依次调用,实现了消息自顶向下的传递。

图4 应用观察者模式时的序列图

3 结论

总体来看,应用设计者模式的优点大于缺点。首先,系统获得良好的可扩展性,可以很容易的向系统中添加新的对象,需要做的只是要那些新加入的对象实现Subject接口或Observer接口,然后,可以在需要它们进行消息传递的时候注册到观察者列表,在不需要进行消息传递的时候注销出观察者列表。其次,对于本系统中参与消息传递的对象,因为发布者和观察者之间并不存在很紧密的联系,它们可以独立地应用在其它的系统中。对其中某个对象的复用不受到另外对象的影响或限制。最后,如果对某个对象进行了修改,不会影响其它的对象,不需要修改已有的对象。所以,采用了观察者模式重新设计以后,系统获得了良好的可扩展性和灵活性,有利于系统的修改和维护。

可以看到,重新设计以后将会带来更多的接口和方法。每个发布者或接受者都需要某个接口去定义。但是对于一个项目来说,这可能会带来管理上的困难,因为跟踪或维护这些类的工作量会增多。

[1] 刘巧红.计算机虚拟校园的建造与人机交互的实现[J].计算机工程与设计,2006,(19):4332 -4335.

[2] Eric Freeman,Elisabeth Freeman,Kathy Sierra & Bert Bates.Head First Design Patterns[M].USA:O’reilly Media,2004:51.

[3] 廖志坚,蒋明亮.设计模式在广东高新区产业地图研究系统中的应用[J].科技管理研究,2011,(2):123-126.

[4] Dan Pilone& Russ Miles.Head First Software Development[M].USA:O’reilly Media,2007:436-437.

[5] Kathy Sierra& Bert Bates.Head First Java[M].USA:O’reilly Media,2007:226.

猜你喜欢

发布者观察者消息
新加坡新法规引争议
一张图看5G消息
“你看不见我”
冷静而又理性的观察者——德国华人作家刘瑛访谈
基于博弈论的社交网络转发控制机制
广告发布者的著作权审查义务问题研究
论虚假广告发布者侵权责任
消息
消息
消息