软件设计模式在铁路调度指挥系统中的应用
2011-02-02刘隽张辉
刘 隽 张 辉
软件设计模式在铁路调度指挥系统中的应用
刘 隽*张 辉**
介绍设计模式的概念以及封装变化的思想,结合铁路调度指挥系统的特点,详细说明了工厂方法、观察者和单件模式的典型应用场景,以及设计模式的综合应用。
设计模式;铁路调度指挥;系统
1 软件设计模式
软件设计模式(Design Patterns)是为解决软件开发领域中多种重复出现的经典问题而提出的解决方案,是面向对象编程经验的总结,是软件设计技巧中最重要的方法和原则。软件设计需要应付不断变化的需求,项目开发需要不断的反复修改更新,解决之道就是封装变化。设计模式是“封装变化”思想的最佳阐释,就是寻找软件中可能存在的“变化”,然后利用抽象对这些变化进行封装。由于抽象没有具体的实现,代表了一种无限的可能性,使得软件系统能够以扩展的方式满足未来的需求变化。
铁路调度指挥系统属于企业级综合性应用系统,包括信息化管理和实时执行控制2大部分,即“管控结合”、“运维融合”类型的计算机应用系统。其主要功能是实现设备设施监视与控制,各类调度指挥计划的编制、调整、执行与反馈,以及调度系统自身的状态维护。目前,中国铁路已进入高速发展时代,规章制度、指挥流程、调度岗位、线路、车辆总在变化,因此铁路调度指挥系统也要与时俱进,适应变化。这也恰好契合了软件开发领域“拥抱变化”的主题。
设计模式从创建、结构、行为三方面提出了封装变化的方案,而铁路调度指挥系统经常要面对设备种类与数量的变更、流程的改善、自身部署规模的增加。因此设计模式在铁路专业软件开发领域是有合适的切入点的。
笔者有幸参与过一些铁路调度指挥系统项目,其中包括列车调度指挥系统(TDCS)、分散自律调度集中系统(CTC)、客运专线运营调度系统(TDS)、编组站综合自动化系统(SAM)、动车基地调度集中系统(ACS)。下面总结设计模式在铁路调度指挥系统中的一些典型应用,与大家分享经验。
2 设计模式的实际应用
2.1 工厂方法模式(Factory M ethod)
工厂方法属于创建型设计模式,用于封装对象创建所引起的可能变化。工厂方法模式结构如图1所示。
图1 工厂方法模式结构
意图:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
适用性:当一个类不知道其所必须创建的对象类的时候;当一个类希望由其子类来指定所创建对象的时候;当类将创建对象的职责委托给多个帮助子类中的某一个,并且希望将哪个帮助子类是代理者这一信息局部化的时候。
准确的说,工厂方法模式是将创建对象实例的责任转移到工厂类中,并利用抽象的原理将实例化行为延迟到具体工厂类。在铁路调度指挥系统中,对设备的管理是一项主要功能,因而在软件中创建设备对象就是实施管理的第一步。
在SAM系统中,电务维护服务器软件需要从局域网中接收大量各种类型设备和操作的实时信息,在进行归类整理并生成数据对象后,或存储,或转发,或图形化展示。由于设备类型、操作内容会随用户需求的发展而变化,为了将变化给软件修改和维护带来的影响减少至最低程度,应该采用工厂方法对生成数据对象这一过程进行封装。
图2中的CCodeData、COperationData和CStatusData分别代表联锁码位信息类、用户操作信息类和设备状态信息类,工厂方法通过对应的CCodeDataFactory、COperationDataFactory和CStatusData-Factory这些工厂类以抽象方法来创建具体的信息类对象。再结合反射、配置文件、表启动法等辅助技术,最终就可以彻底达到解除对具体对象依赖的目标。
图2 SAM系统中的工厂方法模式类图
假设未来需要电务维护服务器接收并处理一种新类型的实时信息,那么只需为其增加一个CData-Base的子类和一个对应的CDataFactoryBase子类即可,软件的其他部分无需改动。
2.2 观察者(Observer)模式
观察者属于行为型设计模式,对可能变化的行为进行抽象,通过封装达到整个架构的可扩展性。图3是观察者模式结构。
意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
图3 观察者模式结构
适用性:当一个抽象模型有2个方面,其中一个方面依赖于另一方面,将这二者封装在独立的对象中,以使它们可以各自独立地改变和复用;当一个对象的改变需要同时改变其他对象,而不知道具体有多少对象有待改变;当一个对象必须通知其他对象,而它又不能假定其他对象是谁。换言之,不希望这些对象是紧密耦合的。
观察者模式中最关键的一点是需要对观察者角色进行抽象,解除观察者与被观察者之间的依赖关系。此外,被观察者即主体(Subject)角色,还需要维护一个集合对象,它是一个观察者对象的列表集合,在消息通知时,被观察者将遍历该集合内的观察者对象,并调用它们的相关方法。
在.NET框架中,由于引入了委托与事件机制,为实现观察者模式提供了一个更简捷的方案。事件的发布者就是主体角色;事件的订阅者则为观察者角色。
在调度指挥系统的用户需求中,要求系统软件对铁路设备的工作状态进行不间断监视,比如在部署CTCS-2级和CTCS-3级列控系统的线路上,TDCS、CTC和ACS等系统都能够动态显示列控中心的综合状态。需求分析的结果是,系统终端能够收到列控中心发来的状态信息;依据状态信息在相关窗体界面上查找到对应的控件;找到控件后,根据当前状态信息修改控件的颜色。
这里存在一个问题:终端应该在更新时查询窗体是否已被关闭,如果已关闭则无需查找并更新控件。但是,这样势必要增加状态信息处理模块对窗体模块的依赖关系,这是软件设计者不希望看到的情况。如果使用观察者模式来实现这一功能,就会大大减弱这种依赖关系,达到事半功倍的效果。
综合状态数据模块是主体,其中定义了更新事件,并能够主动引发事件;监视窗体是观察者,能够主动订阅/取消订阅更新事件,而被动接收事件通知来更新显示内容。二者之间具体的交互过程:监视窗体会在启动后订阅更新事件,在关闭前取消订阅;通信模块依据收到的状态信息来更新数据模块,然后调用数据模块中的事件引发方法;事件被引发后,订阅事件的窗体即获得了通知,它会按照数据模块中的内容来刷新控件显示;无论窗体是否启动,通信模块都要更新数据模块,如果窗体未启动或者已关闭,事件对象维护的观察者列表中就没有记录,因此事件通知就不会发给窗体。
从上述过程中可以看出,通信模块和数据模块根本不需要知道窗体是否存在,这样就达到了解耦依赖关系,以及动态确定是否刷新控件的目的。
2.3 单件模式(Singleton)
单件属于创建型设计模式,它是将创建单件对象的实现逻辑封装起来。图4是单件模式结构。
意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
适用性:当类只能有一个实例,而且客户可以从一个众所周知的访问点访问时;当这个惟一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。
单件模式将那些可能重复的实现逻辑封装为方法或单独的类,则可以避免因这些实现的变化而导致代码所谓“霰弹式修改”(Shotgun Surgery)。
铁路领域的许多设备是惟一标识的,在调度指挥系统中对应的映像也应该具有惟一性,调度指挥系统也需要对一类资源或数据以独占的方式进行使用。在这2个场景中,都可以用到单件模式。
调度指挥系统一般都提供语音提示功能,而且系统中的不同功能模块都需要向使用者发出语音提示,比如联锁和列控设备的管理模块要广播设备报警信息,调度作业模块要播放执行进度。为了避免互相干扰,不同模块的语音提示不能同时并发播出,而应该按照一定的优先级顺序播出。
为满足上述需求,应该为系统设计一个以单件形式存在的通用语音提示模块。所有需要播出语音提示的模块都通过惟一的访问点来调用它,并且要由该模块独立地维护多条语音提示的播放时机和顺序。如果未来对语音提示有新的需求,只需对这个单一的通用模块进行修改即可。
在.NET平台上,可以运用静态类、静态数据成员,结合静态构造器的初始化能力来实现单件模式。如果再辅以多线程技术,就可以得到一个具备后台播放功能的通用语音提示模块。
3 设计模式综合应用
为了应对某个复杂的需求,有时需要将多种设计模式组合起来,形成复合的设计模式。这个过程需要根据项目的实际需求,逐步演化设计。
SAM系统电务维护服务器中,不仅应用了工厂方法设计模式,而且为了确保那些具体的工厂类具有惟一的访问点,节省计算资源,可以对这些工厂类施加单件模式。同样地,在采用观察者模式设计的列控中心综合状态数据模块上,也可以叠加单件模式,这样就能够保证列控中心在系统中具有惟一的映像。
4 结束语
学习并使用设计模式是为了改善设计,让软件能够经受需求不断变化的考验。设计模式不是衡量软件开发者水平的一把标尺,不用设计模式同样可以做出好的设计。不过,若能掌握并合理运用设计模式,对提高设计能力、增强铁路调度指挥系统的稳定性和安全性是非常有益的。
[1] 张逸.软件设计精要与模式.第2版[M].北京:电子工业出版社.
[2] Eric Gamma,Richard Helm,Ralph Johnson,John Vlissides(GOF)著.李英军等译.设计模式——可复用面向对象软件的基础[M].北京:机械工业出版社.
[3] Martin Fowler.UML Distilled:A Brief Guide to the Standard Object Modeling Language(3rd Edition).Addison-Wesley.
[4] Martin Fowler.Refactoring:Improving the Design of Existing Code.Addison-Wesley
[5] JAVA爱好者http://www.javafan.net.
[6] Jeffrey Richter著.李建忠译.Microsoft.NET框架程序设计(修订版)[M].北京:清华大学出版社.
[7] Daniel Solis著.Illustrated C#2008.Apress
The authors firstly introduced the concept of design patterns and the thoughtof change of encapsulation.Based on the features of railway dispatching&command systems,the model scenario of three design patterns,namely factory method,observer,and singleton were illustrated and the synthetic application of design patterns were dealtwith.
Design Patterns;Railway Dispatching&Command;System
中国铁道科学研究院通信信号研究所 100081 北京
*助理研究员 **研究实习员
2011-01-21
(责任编辑:诸红)