摘 要: 针对传统的面向过程的软件设计方法已无法应对市场对燃料电池测试系统快速的需求变化,提出将设计模式应用于燃料电池测试系统软件的开发过程,重点介绍了抽象工厂模式、命令模式、观察者模式、外观模式的应用。实验结果表明,基于面向对象设计模式开发的燃料电池测试系统软件具有良好的架构,实现了程序模块间的低耦合和模块内部的高内聚,提高了程序的可维护性和可复用性,能够灵活应对功能需求的变化。采用该架构开发完成的多款燃料电池测试软件运行稳定可靠。
关键词: 面向对象设计模式; 燃料电池; 测试系统; 软件开发
中图分类号: TN964?34 文献标识码: A 文章编号: 1004?373X(2014)22?0153?04
Application of design patterns in fuel cell test system
HE Bing?lin
(Guangdong Electronic Technology Research Institute, Guangzhou 510630, China)
Abstract: Because the traditional process?oriented software design methods have been unable to cope with rapidly changing needs of the market for fuel cell test system, the design patterns are proposed to apply to the fuel cell test system software development process. Four important patterns, including abstract factory pattern, command pattern, observer pattern and facade pattern, are described in detail. The experimental results show that the fuel cell test system software developed on the base of object?oriented design pattern has a good architecture, as well as implemented low coupling between modules and high cohesion within the module, and make the software more flexible to the functional requirements. The fuel cell test softwares developed with this architecture run stable and reliable.
Keywords: object?oriented design pattern; fuel cell; test system; software development
燃料电池是一种能够将储存在氢燃料和氧化剂中的化学能直接转化为电能的发电装置,它具有能量转换效率高、对环境污染小等优点[1]。燃料电池在世界范围掀起研究的热潮,目前国内外不少公司研制出专门的测试系统,以实现对燃料电池进行性能的评估。燃料电池测试系统(以下简称测试系统)包括测试设备以及配套的测试软件,其中测试软件平台提供用户与测试设备之间操作接口,是整个测试系统的核心。鉴于传统的面向过程的软件开发方法存在的问题,本文将研究如何将设计模式应用于燃料电池测试软件,设计出良好体系结构的系统,从而不仅使测试系统很好地应对快速多变的需求,同时使测试系统具有更好的稳定性、扩展性、维护性。
1 设计模式简介
设计模式是指经过验证的,用于解决在特定环境下、重复出现的、特定问题的解决方案,可以帮助设计者更加简单地复用成功的设计和体系结构[2]。Erich Gamma等人总结了23种常见的软件设计模式,从此设计模式在软件设计和开发中得到广泛的应用。软件设计模式是利用面向对象技术来解决特定环境中的问题的方法,是针对软件设计过程中某个特定环境下出现的问题的可重用软件设计方案[3]。23种常见的软件设计模式在粒度和抽象层次上各不相同,根据其目的可分为创建型、结构型、行为型3种。创建型模式抽象了实例化过程,使一个系统独立于创建、组合和表示构成它的对象,包括抽象工厂、单例等模式;结构型模式处理类与对象的组合,以获得更大的结构,包括外观、代理等模式;行为型模式描述类或对象间交互和职责分配,包括命令、观察者等模式。在实际的应用中,只有深入理解各个设计模式及其相互间的关系,才能很好地将设计模式应用于将要设计的系统。
2 设计模式应用
本文所述的测试系统采用模块化设计,由配气、加湿、电池温控、电子负载、单模检测、报警共6个模块组成:各个模块在测试软件的统一管理调度下协同工作,以实现对气体的流量、压力、温度、湿度等参数的测控,以及模拟燃料电池恒流、恒压、恒功率放电等多种工况;测试软件还为燃料电池测试过程数据提供丰富的表现形式和分析手段,且有完善报警功能,使用户全面掌握电池测试性能[4]。限于篇幅,本文仅以其中4种设计模式的应用举例进行说明,分别是抽象工厂模式、命令模式、观察者模式、外观模式。
2.1 抽象工厂模式
抽象工厂模式意图提供一个创建一系列相关或相互依赖对象的接口,无需指定它们具体的类[2]。在抽象工厂模式中,工厂类与产品类具有平行的对等结构,它们之间一一对应。核心的抽象工厂类不负责所有产品的创建,仅负责给出具体工厂类必须实现的接口,具体产品的创建由具体工厂类去实现[5]。endprint
测试软件在设计中使用到系统参数(如放电功率、电流、电压的最大最小值)、工步集合(如恒流、恒压、恒功率等放电工步)、过程数据(如气体流量、压力、温度)等数据模型,因技术规格不同,每个型号的系统拥有一套数据模型,不同型号系统的数据模型中属性集合不同,或者属性取值范围不同。传统的软件设计方法通常通过条件选择(如switch?case)区分不同型号系统的数据模型,使得数据模型的创建不灵活,并且违背了开放?封闭原则。如果将系统参数、工步集合、过程数据看作一系列的产品,而采用抽象工厂模式实现产品族的创建而无需关心构建过程,只关心什么产品由什么工厂生产即可,那么抽象工厂模式很好地解决了这个问题。
图1给出基于抽象工厂模式创建10与20两套不同型号系统的系统参数、工步集合的结构示意图:抽象产品ISysParam与IWorkStepSet分别为系统参数、工步集合对象定义抽象的操作接口;抽象工厂IFctsFactory为创建系统参数、工步集合对象定义了抽象的操作接口,通过该接口可以实现具体产品;10Factory与20Factory类为具体工厂,其工厂方法CreateSysParam和CreateWorkStepSet分别负责具体系统参数(10SysParam和20SysParam)、工步集合(10WorkStepSet和20WorkStepSet)对象的创建工作。由于具体工厂返回的是抽象产品的实例,从而屏蔽了客户端对具体产品类访问所造成的差异。当创建一套新型号21系统对应的数据模型时,运用“反射+配置文件”的技术【6?7】,不需要修改抽象工厂类和现有的具体工厂类,只需要增加21系统对应数据模型的具体工厂和具体产品,不但遵守了开放?封闭原则,又保持了封装数据模型对象创建过程的优点。
2.2 命令模式
命令模式意图将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作[2]。命令模式定义一个命令接口,用来约束所有命令对象的行为,每个命令实现对象是对客户端某个请求的封装。命令实现对象是虚的实现,它并不知道如何处理命令,但它持有相应的接收者对象来真正执行命令。命令对象和接收者对象的关系不是与生俱来,由装配者对象按需组装。命令模式还提供一个调用者对象持有命令对象,命令发起对象通过调用者对象来触发命令的执行。
图1 抽象工厂模式结构示意图
测试系统的气体流量、加湿温度、电池温度等物理量分别由专门的控制器实现控制,测试软件在设计中需要与这些控制器通信以处理气体流量设定、加湿温度设定、电池控制温度设定等命令的发送。控制器的选型要考虑控制精度、价格等因素,因此不同型号的系统可能选用不同厂家的控制器,不同厂家的控制器提供不同的操作指令,并且采用不同的通信协议。传统的软件设计方法一般针对具体的控制器定义一个控制对象完成所有的处理工作,这样导致代码的耦合性太强,不便于程序的扩展。当更换某个控制器时,必须修改原代码,违背了开放?封闭原则。由于命令模式使得发起命令的对象和具体实现命令的对象完全解耦,因此能够很好的解决这个问题。图2给出了基于命令模式实现氢气、空气流量设定的结构示意图: MFC为质量流量控制器接口,它声明了设定流量的方法;H2MFC与AirMFC是MFC的两个实现类,H2MFC(氢气质量流量控制器)与AirMFC(空气质量流量控制器)都是接收者,它们分别知道如何执行氢气与空气流量设定操作;CMD声明了命令执行操作的接口;FlowSetCmd是流量设定命令,它绑定于某个MFC对象并调用其的DoFlowSet操作,以实现Excute;装配者对象Client创建FlowSetCmd对象,并根据上下文指定它的接收者为H2MFC或AirMFC;调用者对象MFCManager持有FlowSetCmd对象,当命令发起对象触发它的SetFlow操作提交一个流量设定请求,FlowSetCmd对象调用它的接收者对象的DoFlowSet操作完成流量的设定。
图2 命令模式结构示意图
由于发起命令的对象和具体的实现完全解耦:当更换某个质量流量控制器,只需实现新的命令实现对象,并在装配时设置到命令对象中,其他代码完全不用变化;扩展新的命令(FlowClearCmd)也很容易,只需实现新的命令对象,然后在装配时,把具体的实现对象设置到命令对象中,然后就可以使用这个命令对象,已有的实现完全不用变化。
2.3 观察者模式
观察者模式意图定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被更新[2]。这一模式中的关键对象是目标(Suject)和观察者(Observer)。一个目标可以有任意数目依赖于它的观察者。一旦目标的状态发生变化,所有观察者都得到通知。测试软件在设计中需要将过程数据以多种方式(如图形界面、趋势曲线、特性曲线、数据列表、柱状图等)进行表示,这涉及到过程数据状态与多种数据表现方式的状态保持一致问题。如果将过程数据看作目标对象,将图形界面、趋势曲线、特性曲线、数据列表、柱状图等看作观察者。传统的软件设计方法是当目标对象的状态发生变化时,由它直接调用所有观察者对象进行数据的更新,这样导致目标对象与观察者对象的关系过于耦合,不利于程序的扩展。如果使用观察者模式,目标只知道观察者接口,并不知道具体观察者类,从而实现目标类与具体观察者类之间的解耦。一个目标并不需要知道它有几个观察者,也不需要知道具体是哪一个观察者。图3为基于观察者模式实现过程数据发布的示意结构图:观察者Observer为当目标发生改变时需要获得通知的对象定义一个更新接口;目标Subject可以拥有任意多个观察者,并提供注册、删除和通知观察者对象的接口;图形界面MainForm和曲线界面CurveForm为具体的观察者;过程数据分发者ProcessDataDispatcher为具体目标;客户端通过Attach接口将MainForm和CurveForm注册进ProcessDataDispatcher,表示MainForm和CurveForm希望订阅过程数据;一旦过程数据发生变化,ProcessDataDispatcher通过NotifyObservers接口通知所有观察者;各个观察者就可通过Subject.GetData获取更新后的过程数据。观察者模式允许在不改动目标和其他观察者的前提下增加观察者DataListForm、HistogramForm等,从而允许建立动态、可靠和灵活的系统。
图3 观察者模式结构示意图
2.4 外观模式
外观模式意图为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用[2]。
为了提高测试系统软件的可重用性,通常把它分割成多个子系统,例如启动工步子系统、查看曲线数据子系统、设置系统参数子系统等等。各子系统内部由更小的模块组成,如果客户端直接使用子系统的功能,它通常需要和子系统的多个模块交互,任意一个模块的变动将会引起客户端的变动。本文通过为每个子系统建立一个外观来封装客户端与子系统的交互,如图4所示:StartWorkFacade外观为工步子系统提供了StartWork和StopWork接口,方便客户端进行启动和停止工步的操作;ViewCurveFacade外观为曲线数据子系统提供DisplayRealtimeData和DisplayHistoryData接口,方便客户端进行查看实时和历史数据的操作;SetSysParamFacade外观为系统参数子系统提供SetParam和ModifyParam接口,方便客户端进行设置和修改系统参数的操作。
通过使用外观模式:不仅封装了子系统外部和子系统内部多个模块的交互过程,从而简化了外部的调用;而且松散了客户端与子系统的耦合关系,让子系统内部模块能更容易扩展和维护[8]。
图4 外观模式结构示意图
3 结 语
本文虽然仅以抽象工厂模式、命令模式、观察者模式、外观模式为例讲述设计模式在测试系统软件中的应用。但在测试系统软件开发各阶段还使用到如下设计模式:在文件存储和日志管理中应用了单例模式,保证在系统运行期间一个类只有一个实例并且该实例易于外界访问,从而节约了系统资源;在控制器命令和数据库存储过程的执行步骤应用了模板方法,这样可以将代码的公共行为提取出来,达到复用的目的。在网络通信应用代理模式,根据用户选择的通信方式(如以太网、RS 485、CAN)委托相应的通信驱动程序完成数据的收发。正是由于在测试系统软件的开发过程广泛运用了设计模式,实现了程序模块间的低耦合和模块内部的高内聚,提高了程序的可维护性和可复用性,能够快速应对客户需求的变化,成功设计出FCTS10、FCTS20、FCTS21等多个型号的测试系统。本文论述的设计模式具有一定的通用性,对于其他测试系统软件开发具有一定的参考价值。
参考文献
[1] 詹姆斯·拉米尼,安德鲁·迪克斯.燃料电池系统:原里·设计·应用[M].2版.北京:科技出版社,2005.
[2] GAMMA Erich, HELM Richard, JOHNSON Ralp.设计模式:可复用面向对象软件的基础[M].李英军,马晓星,蔡敏,等译.北京:机械工业出版社,2000.
[3] 庄立伟,卫建国,毛留喜.软件设计模式在农业气象系统开发中的应用[J].应用气象学报,2011,22(5):631?640.
[4] 杨成胡,何炳林,梁柱扬,等.质子交换膜燃料电池测试系统的研发[J].计算机测量与控制,2013,21(10):2627?2629.
[5] 雷金勇,李鹏,于学军,等.面向对象的设计模式在暂态仿真中的应用[J].电力系统及其自动化学报,2012,24(3):35?40.
[6] 陈臣,王斌.研磨设计模式[M].北京:清华大学出版社,2011.
[7] 程杰.大话设计模式[M].北京:清华大学出版社,2007.
[8] 秦小波.设计模式之禅[M].北京:机械工业出版社,2010.
图3 观察者模式结构示意图
2.4 外观模式
外观模式意图为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用[2]。
为了提高测试系统软件的可重用性,通常把它分割成多个子系统,例如启动工步子系统、查看曲线数据子系统、设置系统参数子系统等等。各子系统内部由更小的模块组成,如果客户端直接使用子系统的功能,它通常需要和子系统的多个模块交互,任意一个模块的变动将会引起客户端的变动。本文通过为每个子系统建立一个外观来封装客户端与子系统的交互,如图4所示:StartWorkFacade外观为工步子系统提供了StartWork和StopWork接口,方便客户端进行启动和停止工步的操作;ViewCurveFacade外观为曲线数据子系统提供DisplayRealtimeData和DisplayHistoryData接口,方便客户端进行查看实时和历史数据的操作;SetSysParamFacade外观为系统参数子系统提供SetParam和ModifyParam接口,方便客户端进行设置和修改系统参数的操作。
通过使用外观模式:不仅封装了子系统外部和子系统内部多个模块的交互过程,从而简化了外部的调用;而且松散了客户端与子系统的耦合关系,让子系统内部模块能更容易扩展和维护[8]。
图4 外观模式结构示意图
3 结 语
本文虽然仅以抽象工厂模式、命令模式、观察者模式、外观模式为例讲述设计模式在测试系统软件中的应用。但在测试系统软件开发各阶段还使用到如下设计模式:在文件存储和日志管理中应用了单例模式,保证在系统运行期间一个类只有一个实例并且该实例易于外界访问,从而节约了系统资源;在控制器命令和数据库存储过程的执行步骤应用了模板方法,这样可以将代码的公共行为提取出来,达到复用的目的。在网络通信应用代理模式,根据用户选择的通信方式(如以太网、RS 485、CAN)委托相应的通信驱动程序完成数据的收发。正是由于在测试系统软件的开发过程广泛运用了设计模式,实现了程序模块间的低耦合和模块内部的高内聚,提高了程序的可维护性和可复用性,能够快速应对客户需求的变化,成功设计出FCTS10、FCTS20、FCTS21等多个型号的测试系统。本文论述的设计模式具有一定的通用性,对于其他测试系统软件开发具有一定的参考价值。
参考文献
[1] 詹姆斯·拉米尼,安德鲁·迪克斯.燃料电池系统:原里·设计·应用[M].2版.北京:科技出版社,2005.
[2] GAMMA Erich, HELM Richard, JOHNSON Ralp.设计模式:可复用面向对象软件的基础[M].李英军,马晓星,蔡敏,等译.北京:机械工业出版社,2000.
[3] 庄立伟,卫建国,毛留喜.软件设计模式在农业气象系统开发中的应用[J].应用气象学报,2011,22(5):631?640.
[4] 杨成胡,何炳林,梁柱扬,等.质子交换膜燃料电池测试系统的研发[J].计算机测量与控制,2013,21(10):2627?2629.
[5] 雷金勇,李鹏,于学军,等.面向对象的设计模式在暂态仿真中的应用[J].电力系统及其自动化学报,2012,24(3):35?40.
[6] 陈臣,王斌.研磨设计模式[M].北京:清华大学出版社,2011.
[7] 程杰.大话设计模式[M].北京:清华大学出版社,2007.
[8] 秦小波.设计模式之禅[M].北京:机械工业出版社,2010.
图3 观察者模式结构示意图
2.4 外观模式
外观模式意图为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用[2]。
为了提高测试系统软件的可重用性,通常把它分割成多个子系统,例如启动工步子系统、查看曲线数据子系统、设置系统参数子系统等等。各子系统内部由更小的模块组成,如果客户端直接使用子系统的功能,它通常需要和子系统的多个模块交互,任意一个模块的变动将会引起客户端的变动。本文通过为每个子系统建立一个外观来封装客户端与子系统的交互,如图4所示:StartWorkFacade外观为工步子系统提供了StartWork和StopWork接口,方便客户端进行启动和停止工步的操作;ViewCurveFacade外观为曲线数据子系统提供DisplayRealtimeData和DisplayHistoryData接口,方便客户端进行查看实时和历史数据的操作;SetSysParamFacade外观为系统参数子系统提供SetParam和ModifyParam接口,方便客户端进行设置和修改系统参数的操作。
通过使用外观模式:不仅封装了子系统外部和子系统内部多个模块的交互过程,从而简化了外部的调用;而且松散了客户端与子系统的耦合关系,让子系统内部模块能更容易扩展和维护[8]。
图4 外观模式结构示意图
3 结 语
本文虽然仅以抽象工厂模式、命令模式、观察者模式、外观模式为例讲述设计模式在测试系统软件中的应用。但在测试系统软件开发各阶段还使用到如下设计模式:在文件存储和日志管理中应用了单例模式,保证在系统运行期间一个类只有一个实例并且该实例易于外界访问,从而节约了系统资源;在控制器命令和数据库存储过程的执行步骤应用了模板方法,这样可以将代码的公共行为提取出来,达到复用的目的。在网络通信应用代理模式,根据用户选择的通信方式(如以太网、RS 485、CAN)委托相应的通信驱动程序完成数据的收发。正是由于在测试系统软件的开发过程广泛运用了设计模式,实现了程序模块间的低耦合和模块内部的高内聚,提高了程序的可维护性和可复用性,能够快速应对客户需求的变化,成功设计出FCTS10、FCTS20、FCTS21等多个型号的测试系统。本文论述的设计模式具有一定的通用性,对于其他测试系统软件开发具有一定的参考价值。
参考文献
[1] 詹姆斯·拉米尼,安德鲁·迪克斯.燃料电池系统:原里·设计·应用[M].2版.北京:科技出版社,2005.
[2] GAMMA Erich, HELM Richard, JOHNSON Ralp.设计模式:可复用面向对象软件的基础[M].李英军,马晓星,蔡敏,等译.北京:机械工业出版社,2000.
[3] 庄立伟,卫建国,毛留喜.软件设计模式在农业气象系统开发中的应用[J].应用气象学报,2011,22(5):631?640.
[4] 杨成胡,何炳林,梁柱扬,等.质子交换膜燃料电池测试系统的研发[J].计算机测量与控制,2013,21(10):2627?2629.
[5] 雷金勇,李鹏,于学军,等.面向对象的设计模式在暂态仿真中的应用[J].电力系统及其自动化学报,2012,24(3):35?40.
[6] 陈臣,王斌.研磨设计模式[M].北京:清华大学出版社,2011.
[7] 程杰.大话设计模式[M].北京:清华大学出版社,2007.
[8] 秦小波.设计模式之禅[M].北京:机械工业出版社,2010.