模块设计与实现经验总结(三)

来源:互联网 发布:mac开发人工智能软件 编辑:程序博客网 时间:2024/06/06 07:52

3  模块详细设计指南与规范

模块详细设计要完成两个方面工作:一是明确模块的功能需求和非功能需求、二是设计如何完成和实现模块的功能需求,包括类结构、线程结构设计等。本节根据后台模块特点,描述了两部分工作需要考虑和设计的关键点。

3.1确定模块的功能规格

1) 本模块概述

概述主要描述了本模块所属子系统,以及在子系统中所承当职责的简单描述。

2) 本模块在系统中与周围模块关系和交互情况

很多模块一般要依赖周围的模块或者数据库,为此建议以图形方式描述本模块与本模块依赖的其他模块或者数据库之间交互情况。交互方式主要包括:

基于接口调用的交互、基于数据流的交互,直接访问数据库。

基于接口交互要描述:接口实现方式(ICEWCF)、接口调用目的、以及什么时候调用等。

基于数据流交互要描述:传输数据类型,传输方式等。

对数据库或者存储要描述:需要访问的数据库名称、表格名称以及表格存储数据含义、访问数据库中表格的目的等。

3) 本模块部署角色以及对基础软硬件要求

描述本模块将要部署的角色、部署模式、对操作系统要求、对基础软件要求、对硬盘要求、对内存要求等。

部署模式主要考虑是分布式多机部署、还是只会单实例部署。

操作主要考虑需要对操作系统版本的要求。

基础软件主要包括:jdk版本要求、需要安装其他基础软件以及版本等。

对硬盘要求:是否需要临时存储、大概需要多大(尽量能不用存储就不用)

对内存要求:大概需要多大内存等。

4) 本模块所处理数据的数据格式描述

对数据预处理模块,描述本模块对待处理数据的格式的假定和要求。

5) 本模块调用接口描述

详细描述清楚需要调用接口:接口名字、参数类型、参数单位、接口功能、接口执行时间要求(超时处理)、分片传输(消息大小限制导致分片传输需求)。接口功能部分重点要描述清楚异常情况下接口返回值和应该执行操作,例如调用的接口是否会返回NULL等。

6) 本模块功能性需求描述

以功能点方式详细描述本模块功能。

如果是涉及对外提供接口的,明确描述:接口名字、参数类型、参数单位、各种输入参数下预期行为和返回值、接口应该满足执行时间要求。

7) 例外与异常情况下描述与处理要求

详细考虑本模块第2)3)4)5)中所描述本模块依赖的外部环境不满足本模块要求情况下的处理方式。

 

3.2设计与实现部分

1) 关键问题与策略

只要有一点复杂或者难度模块的设计工作都会存在几个有难度或者关键问题去解决,这些关键问题的解决方案好坏决定了整个模块实现质量。一般而言这些关键问题解决方案会有多种,并且有好有坏,且会存在较大争议。相反一般非关键点设计就比较没有异议。

关键问题与策略是开展设计评审的重点。模块设计评审就是审查两点:是否存在有些关键问题没考虑到、二是每个关键问题的解决方案是否是最优的。

因此要求模块设计人员,在确认了功能规格后,第一件事就是要考虑本模块设计中存在哪些关键问题,然后再思考对应解决方案。在确定了所有影响比较大的关键问题的解决方案之后,剩余的类结构设计和线程设计等就会比较顺利。

此部分要求设计人员要反复问自己:一是否所有值得斟酌的问题都想到了、二目前设计的策略是否是最好的(好的策略一般是简单策略),要敢于否定自己已经设计好的策略。

衡量优秀实现策略的标准是:“用最简单方式满足最重要需求”。后台设计过程中要避免的事情是:不要为了某个不常用、但是听起来很美好的功能点导致设计很复杂。有时候为了模块运行简单和稳定,宁肯不要太完美。特别是很多时候很多需求是矛盾和有冲突的,作为设计人员一定要能识别哪些是主要需求,哪些是次要需求。

例如某全文检索检索模块,第一版本为提高检索性能,设计了检索结果缓存功能。但是实际使用过程中发现缓存命中概率很低,而这个功能导致整个模块设计复杂很多。

 

2) 静态类结构设计

类结构设计,主要设计出本模块主要类以及类之间的关系,并利用类图的方式表达出来。

在静态类结构设计中,除类图外,还需要对各个类的职责分工,以及类中主要的方法要进行描述。另外要仔细考虑哪些类是主动类。

在静态类结构设计好坏,主要取决与设计人员面向对象设计的能力。要求设计人员考虑以下几个方面:

ü 是否可以采用现成的设计模式。

ü 是否违反了面向对象的几个原则:单一职责原则、开放封闭原则、替换原则、依赖倒置原则、接口隔离原则。

为了提高自己此方面设计能力,希望大家多看一些面向对象设计方面的书,以及一些经典优秀开源软件的结构,能真正领会设计模式和面向对象的几个原则的精髓,并能指导自己模块类结构设计。

另外如果感觉自己负责多个模块存在重复部分,例如感觉可能几个模块大的处理步骤基本相同,只是在处理细节上不同,则可以考虑将其中相同部分抽出来设计成一个具备一定通用性的框架或者共用代码,并贡献出来。

 

3) 线程结构与同步互斥策略设计

后台模块一般会涉及多线程的处理,因此线程结构设计是后台组模块设计经常会遇到的问题。

ü 线程结构设计必须描述以下几个部分:

ü 包括那几类线程以及每类线程的职责

ü 每类线程的个数

ü 每类线程的启动和停止时间

ü 线程间的协作关系:消费者-生成者关系、同步互斥、共享变量等。

为了清楚描述和思考同步互斥问题,建议采用图的方式划出每类线程与每类线程会访问到公共对象,这样就能很直观识别出需要保护的对象,然后在详细设计和描述同步互斥策略。

线程结构设计基本经验是:

ü 尽量减少线程间的交互。例如有三类线程,本来可能需要每类之间都要交互,则可以考虑以以某类线程作为枢纽,其他两类线程都和该线程交互,而其他两类线程之间不交互。

ü 同步互斥在后台性能不是很重要情况下,可以考虑加锁的粒度粗一点。例如多个线程都要从一个队列取任务,并执行任务,且修改任务状态,则可以每次都锁整个队列,包括修改队列中某个任务的状态也变成队列类中的一个被同步保护的方法,而不是直接调用任务类的修改状态的方法。

ü 被同步互斥保护代码禁止有访问数据库、访问文件、调用远程接口等操作,必须都是只访问本地内存的操作,确保不会长期被锁住。被同步互斥保护代码只应该是“控制”代码而不能是“干活”的代码。

 

4) 主要执行流程

描述本模块所需要处理的主要业务事件对应的处理过程。建议多采用泳道图来表示,好处是能直观的看到各类在该业务处理过程中的职责,方便设计人员对类的职责进行调整。

 

5) 模块配置项设计

 模块配置项设计主要为提高模块通用性,减少模块修改,让设计人员多考虑将很多参数作为配置而不要写死。

对于配置项考虑:

ü 哪些配置项是全局配置、哪些配置项只是本模块需要读的。

ü 哪些配置项和建设方案有关、哪些配置项和建设方案无关。

对全局配置项和与建设方案有关的配置项,应该放入到系统配置中去。方便系统部署时,可以实现设备安装与建设方案无关,实现设备安装程序标准化。

 

3.3与应用运维相关的考虑

为了与即将实现的应用运维系统进行对接。每个模块在设计时要考虑两个方面问题:一是如何从模块外面对模块运行状态进行监控,以及判断模块是否正常运行的标准是什么;二是如果是因为外部环境无法满足本模块要求,则在日志里面表达清楚。

0 0