前面我们梳理了需求分析的相关内容。完成需求分析后,会输出指导软件开发的需求规格说明书。有了该文档的支持,下一步就是系统设计阶段,用于将软件需求的内容转换为可指导软件开发的概要设计和详细设计文档。下面我们从理论和实践上看看如果做系统设计。
1 信息系统建模常见方法及相关概念
通常,系统设计的主要工作就是系统建模。系统建模的主要方法分结构化建模方法和面向对象建模方法,分别与结构化分析和面向对象分析对应。
首先,我们看结构化建模方法。这一方法的切入点是数据设计,指导思想是程序=算法+数据结构。在结构化分析中,我们的手段主要有数据流图DFD,数据字典,判定表,判定树,形式化语言等。有了这些数据信息,那么设计阶段就需要对数据进行加工处理了,围绕数据,要设计软件流程。采用的手段有业务流图,程序流程图,PAD图,NS流程图等。通过这些流程图,梳理对数据的处理过程,在一定意义上就是形成了算法,配合数据的定义,就具备构成软件功能的雏形。
上述分析手段中,程序流程图运用最为广泛。程序流程图由处理步骤、条件判断、控制流向等元素构成,结构简单清晰,便于理解,易于修改。它的缺点是重点突出了流程,自然就隐藏了相关数据。NS流程图又称为盒图。通过这种结构化图示手段,可以比较清晰的展示全局和局部的数据作用域,对于描述嵌套和层次关系也是比较方便的。自然,因为不能随意转移控制,缺少流程线,使得流程的展示不那么清晰自然。PAD图是一种改进的图形方式,可以用来替代程序流程图,它也更加直观,清晰,能反映自顶向下的过程,而且可以通过工具,自动转换为高级语言源程序,具有强大的表达能力。
除了上述的图形工具外,还有表格工具和伪语言用来描述算法。
结合这些工具,结构化建模容易通过自顶向下,分模块,逐步细化的方式完成对系统的设计工作。模块之间的关系构成了系统的总体结构,是概要设计阶段的主要任务。详细设计阶段完成模块的细化工作,包括模块的输入输出,处理流程等。
结构化设计有一些原则要掌握,特别是模块的划分,其好坏,直接影响到系统的复杂程度,稳定性,可扩展性,健壮程度等。模块化的第一个原则是信息隐藏和抽象。这决定了模块划分是否能够很好的应对变化。抽象的好坏,也在一定程度上影响软件的可读性,可理解性和实现便利性。抽象层次通常包括过程抽象,数据抽象和控制抽象。模块的另一个原则是高内聚,低耦合。内聚和耦合可分级定义,就耦合来讲,包括非直接耦合,数据耦合,标记耦合,控制耦合,通信耦合,公共耦合,内容耦合。像内容耦合,就是需要极力避免的。对于内聚而言,包括功能内聚,顺序内聚,通信内聚,过程内聚,时间内聚,逻辑内聚以及偶然内聚。像偶然内聚,就不是很好的理由。以上是理论方面的一些知识,这些内容跟兵法理论一样,要切忌纸上谈兵,更多时候,是需要根据实际情况灵活应用并加以应对的。
结构化建模方法的缺点是容易遗漏信息,模块化分解、抽象难度大,应对变化能力不足,后期风险明显;优点是容易理解,容易实现,可快速上手。
第二种是以数据为中心的信息工程建模方法,类似数据库建模方法,手段有ER图(实体关系图)。因为围绕数据,而数据的稳定性强,自然其优点就是稳定,共用性强,虽然具体流程可能发生变化,但是数据关系可保持稳定。缺点是缺少操作描述(实体关系图主要描述实体、属性及关系,不像面向对象,有操作集描述),还需要二次处理。该方法一般作为其他手段的补充,不独立应用。
第三种是面向对象建模方法,将过程与数据集成到对象中,常采用的手段有统一建模语言UML。对象是一个抽象概念,是对现实物理世界的抽象。将现实中的实体及其附着在其上的操作抽象为类,从而在软件世界中完美映射了现实世界。但是在抽象过程中,需要注意,现实世界抽象的事物并不一定都是有实体对应的,有一些是为了理解和处理方便,而人为引入的。所以,类也就分为了实体类、控制类和边界类。
对于UML,在前面面向对象的需求分析中就已经介绍过了。这里主要介绍在系统设计阶段的应用。通常在分析阶段,我们有了用例,提取出了对象和类,描述了对象之间的关系,构建了包,但是缺少对象的处理流程,这些就需要通过时序图(顺序图、序列图)、协作图(通信图)、活动图、状态图、交互概览图(时序图加活动图)、计时图等描述动态过程的模型图来细化说明。
当然,需求分析过程也可能涉及一部分动态处理,比如通过活动图交互图等来协助梳理需求,确认对需求的理解是否正确等。
类及其包、构件图可以用于描述系统的顶层和全局设计,而上述各种动图可以用于描述系统的详细设计。
基于UML的设计整体过程可以描述如下:
有了上面的理论知识,下面我们看看实际应用中,该如何采用这些方法,为什么这样做,有什么好处和缺点等。
2 上述建模方法在系统中的应用
同前面其他几项主题,由于现代软件系统的复杂性,实际应用中都是多种方法综合实施,很少有只采用一种方法从头贯穿到尾的情况,系统设计也不例外。
还是以前述某电力系统项目为例。该系统大的功能包括注册服务、会商服务、作业服务、线路巡检服务、智能辅助服务、安全警报管理、用户管理、设备管理、地图服务。这些是通过大屏系统直接可见的功能,其下面还有许多二级甚至三级服务,比如流媒体服务,提供推流拉流服务,还提供语音代理服务。会商服务下面还包括录像服务、文件服务、画面管理等功能。智能辅助服务包括智能识别、智能分析等业务。地图服务下面包括定位、天气等服务。线路巡检下面又包括电路电流电压温度采样、局放采样等功能。除此,还有许多不可见的功能,比如安全连接、多通道绑定等基础设施支持。
上述众多功能中,部分是已有系统完成的,部分是根据业务需求需要新增的,但最终对外提供的是一个一致的管理系统。为了实现该项目的目标,在系统设计阶段,团队采用了如下一些方法。
首先是已有功能的重构设计。因为这部分已经有了运行系统,所以在新需求补充下,对新系统的设计,可以参考已有设计,吸取之前的经验,然后做进一步的完善。尽量不做大的修改,重点考虑已有设计存在的问题,梳理这些问题,作为新设计的参考,然后确定是否可以找到比较好的能够平衡时间和实现的方案。因为已有系统的文档中包括了比较完善的时序图、类图、协作图、状态图等架构资料,所以针对新的需求的设计,主要是确定这些架构设计是否满足要求,是否有需要改进或增删的地方。最开始团队主要将工作重心放在围绕需求中的功能描述与设计文档的一一对应上,确定需求和设计是否一致。但是实践中发现,原来的流程设计是从头到尾,一气呵成的,比较完整,成体系,现在原系统主要设计人员已经离职,对原系统的设计缺少意图方面的解释,为了某个变动,设计人员这里改一点,那里补一点,走到后面就发现,跟前面出现了一些矛盾的地方。比如,就定位而言,原来的设计是将其绑定在参与会商的人员上,与会商本身有关联,现在因为业务变动,有地图服务,定位就需要是一个完整的服务,跟会商本身应该是独立隔离才对,这就需要改变包括流程和协议方面的内容。但是仅仅考虑将之前的协议迁离出来是不行的,因为原来节点之间是直接传递定位信息的,在新系统中,当参与系统的节点较多时,节点之间如果还是直接传递定位信息,那么N个节点将需要N平方的信息量,这会对性能产生影响,是不合理的。当出现这些情况后,团队决定暂停原来的方式,迅速转移重心,转而采用以数据为中心的方式来做建模和设计。将从流程的切入点转变为从数据库表的切入点。对原来的数据库表做新的分析,确定哪些表要修改,哪些表不用变动。这样先完成底层数据的归集整理,形成可靠的数据底座。然后从数据基础触发,确定关联类和操作。这一步完成类的重构设计,根据新的设计确定类的结构和关系,确定类的属性和操作。完成这一步的重构设计后,团队对整个原系统的全貌和顶层有了更加深入的理解,同时对新系统的全貌和顶层架构也有了更加清晰的认识。围绕着类的重构,团队回过头来,继续对流程进行梳理和重构。此时,流程的变动处理就轻松许多,主要围绕着四类工作展开,一是筛选保留已有可重用的设计文档,构件;二是筛选可简单修改后可重用的设计文档,构件,并趁热打铁开展设计和评审工作;三是丢弃或重新设计新的流程和相关协议,这部分是重点工作;四是根据新的设计,明确需要补充的设计文档和构件,这部分工作按照微服务设计理念,独立设计实现。能够跟原来系统分离的尽量分离,减少耦合,减少历史包袱。
虽然团体在梳理数据的过程上花费了一些精力和时间,但是磨刀不误砍柴工,这些工作对后续其他模块的设计产生了积极的帮助效果。比如在推流拉流上,因为原理数据包的构成关系比较特殊,进行交错和前项纠错处理,包有拆分重组处理,正是在数据梳理过程中明确了这些信息,才在后面的媒体流格式转换矩阵的构建中很好的避免了非标内容的干扰和影响。而且媒体流引擎的构建也采用了对象建模方法,主要是对数据流进行了抽象,支持多态特性,统一抽象为流,不仅仅是视频流,还有音频流,图形流,还抽象了控制流,定位流,传感器流等等。所以这种方法在其他业务服务的设计中也都得到了很好的应用,最终使得整个系统的业务流表现的比较统一,形成了一个有机整体。
虽然面向对象设计是当前主流,但是结构化设计也有其优势。对于系统的升级功能,因为有很多定制字段,且整个流程的大方向还是比较清晰的,故采用了程序流程图的方式进行了设计。这种设计还有一个好处,就是比较清晰易懂,对该流程的评审,就邀请了用户、市场和技术支持人员共同参与,大家都能够理解整个流程,也就是有统一的场景和语境理解,可采用统一的概念和术语表达对整个过程的建议。通过用户和市场及技术人员参与评审,可有助于研发更好理解用户网络的限制要求,从而做针对性的修改设计。在本系统中主要是全流程加密要求,从升级包到升级通道,且因为业务关系,不允许在使用过程中进行升级,所有升级要么在开机立即完成,要么跳过,这些在前期需求收集阶段都是没有体现的。
其他还有像线路图设计,采用了模型化方法,使用类似伪语言方式,设计一个图形生成器,通过将图示语言化,然后自动转换为web图形,方便了后续的增删查改操作,方便了样式的统一修改,也提升了开发效率。另外作业管理这块的设计甚至采用了外购方案。因为是比较类似通用的工作流模式,最开始技术选型时倾向于采用activiti来做工作流设计,但开始设计时,发现整个工作其实是比较模式化的,而且与团队主要成员技术方向和团队规模都不是很匹配,很适应。考虑到现在这块有很多成熟好用的方案,所以团队综合考虑后,决定引入第三方成熟的方案做定制化设计。通过对比国内几家方案提供商,选择了其中一家文档比较清晰,价格合理,可支持定制化的方案商,由技术支持团队和前端共同安排人员组成小组进行设计实现。选择外购方案后,主要工作其实就由研发转向了业务流构建,技术这块在前端提供对接支持,极大的减轻了开发压力,使得团队能够将重心集中到核心业务上,有力的保证了项目的顺利推进。
通过采用上述设计方法,团队在有限的时间内,高效完成了已有系统的改造和整合,同时顺利的加入了新业务功能,对接了新产品,基本实现了整个项目目标,为市场和营销提供了有力支撑。
当然,在整个设计实施过程中也遇到了一些问题,这是后续需要加强和改进的。一是为了系统的设计统一,实现统一,方面框架化构建,进行了数据流抽象设计,但是这增加了数据流的非标准化成分,特别是像音视频这些实时流。在媒体音频中,还需要进行数据的二次处理,其实是增加了一部分工作,后期团队考虑的基本方案思路是保留数据流的统一设计,但是在实现上进行改进,首先源头数据首先标准化,然后再封装为流,而在引擎中心二次处理时,只需要简单自动化的偏移指针即可实现非标准数据转化为标准化数据流,为对接其他标准系统,引入高质量开源处理组件,提供更好的支持。
其次是网络基础组件方面的问题。因为音视频业务对带宽和性能的要求,当节点增加时,利用现有云计算基础设施框架,将是未来更好的方向。在这部分,后续团队将聚焦与入会对现有业务流进行分流,根据是否要求加密,是否实时性等特性,对服务进行二次拆合设计,将电网要求的内网数据统一走加密内网通道,可以走统一互联网的数据,逐步上云,实现私有云和公有云业务在数据层面的独立和展示层面的统一。这也是架构的新目标。