已阅读5页,还剩5页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
当开始进行模块开发时,系统负责人会给模块开发负责人描述模块功能与要求,但是此时模块功能与需求一般是比较粗线条和不完备的,例如很多细粒度异常情况处理需求一般系统负责人可能会考虑不到。模块负责人通过详细设计完成:细化和确定模块的功能(包括异常处理需求)、识别关键问题和实现策略与流程、以及主要静态类和线程结构设计等。详细设计完成并通过评审之后,模块负责人根据详细设计指导,进行编码并实现模块。需要指出的是即使详细设计,但一般只是初步设计了主要的类和线程结构,以及一些比较大方面的异常情况处理。虽然可能不同的人完成的详细设计的细致粒度存在差别,即使是设计比较细致的详细设计一般不能到达可以直接根据详细设计自动生成代码的粒度,当然个人认为类和线程结构等实现方面的设计也没有必要太过细致,要把握好度,不要太过也不要不够。因此即使在编码和实现阶段其实也存在大量的设计工作,此时设计的粒度较为细致,一般是类级别的详细设计和编码实现(包括详细划分和确认类的功能规格说明书,并实现类的功能)。虽然个人认为在详细设计阶段类和线程结构等实现方面的设计不必要太过细致,但是对模块功能规格(包括异常处理需求)的确认和细化一定要尽可能细致和想全。对关键问题和实现策略也一定要尽可能的细致和想全。对实现方面的类和线程结构设计能够想细还是细的为好,即尽量想细一点为好。所谓“谋定而后动”,只有先设计好了,想好了后面才能少出错。根据上面论述,我们可以得出不管是详细设计还是编码实现都包括两个阶段工作:首先确认和细化功能规格,然后是实现功能规格。对详细设计而言是确认和细化模块的功能规格,并初步设计如何实现模块功能。对编码实现而言是确认和细化各个类的功能规格,然后实现各个类功能,最终实现模块功能。而导致模块质量不高的主要原因是整个开发过程,没有明确地区分“确认和细化功能规格”和“实现功能规格”两个阶段,很多开发者的开发过程是两个过程混在一起,整个过程属于没有明确方向和不断变化的状态,恶果是导致很多例外情况没有考虑到并进行妥当处理,最终导致大量BUG的出现。具体表现如下:详细设计时,模块功能需求确认不够细致,甚至是一直到编码实现阶段都是处于模糊状态,导致很多情况没有想到。例如各个对外提供接口的功能细节,特别是在一些异常情况下的返回值细节或者响应细节都不是很明确。详细设计时,不仔细考虑会存在哪些异常情况,以及设计相应异常处理措施,导致在设计阶段很多异常根本没有考虑。详细设计时,不识别模块实现中关键问题,导致很多关键实现策略要到编码时才确定,但是由于编码时一般思维焦点是当前类,导致确定实现策略时缺乏全局考虑,同时加上还要考虑如何实现,因此会导致采用不是最优的或者是错误的实现策略。详细设计时,类、类状态变化、线程结构设计等考虑太粗。由于详细设计时能不考虑具体实现,会忽略一些细节,这样更能集中精力从整体和全局来考虑一些关键的实现策略和以及类和线程结构设计。而实现阶段一般更加关注细节,但只关注当前类细节和局部细节,因此详细设计时类、类状态变化、线程结构设计等考虑太粗会导致这些问题遗留到开发阶段,使得整个编码过程混乱,最终很多例外情况想不到。至少要保证详细设计完成后,模块开发者能在自己大脑里面把模块跑起来。编码实现阶段,还没有制定清楚每个类、类方法的详细功能规格说明(即要处理哪些情况,异常情况下如何处理等)的情况下,就开始编码实现。明确区分两个阶段的好处是每次大脑只需要集中精力考虑一个方面问题,这样大脑考虑问题会比较轻松,使得问题能够容易想全,出现纰漏的概率要小一些。1详细设计过程明确划分为两个阶段第一个阶段是明确模块的需求,能够以详细的功能规格说明书的方式,明确模块的功能需求,重点考虑模块要处理哪些例外和异常情况,尽自己最大努力把情况想全。例如对本模块对外提供的接口要详细写清楚,各种输入参数情况下的行为是什么,以及返回什么值。对本模块要调用的外部接口,要写明白本模块要求的响应是什么,以及调用失败情况下的处理策略等。此阶段同时要描述清楚本模块运行环境包括:与周围模块交互描述、对内存以及磁盘的要求等对外围环境的需求、模块部署方式(多机并发部署、还是单节点运行)等。注意此时只集中精力考虑需求,不要考虑如何实现。第二阶段是设计中的实现阶段。此阶段要求必须包括有:关键问题与实现策略、主要静态类图设计和说明(主要类、主要方法说明)、线程结构说明(包含哪几类线程、每类线程个数、每类线程职责、每类线程会访问到的类和对象等,如果比较复杂则要说清楚为什么这些设计,设计目标是解决什么问题)、在线程结构基础上描述互斥策略以及线程间关系等、主要的处理活动图(个人推荐更多使用泳道图,能更直观看到对象之间的职责划分和交互过程)。如果类对象的状态比较多,则建议采用状态机图的方式描述清楚,并通过审查状态机变化来检查是否有情况没有处理。2编码阶段建议采用三个步骤n先想清楚,并写出类和每个方法详细功能规格说明(可以先把类名和方法名写好,然后以注释的方式把类的职责、关键实现策略、以及每个方法的功能规格说明)。n根据规格说明中列举情况,写出相应测试代码。n编写实现代码,并通过测试。3编写模块功能规格说明书,重构代码经过编码阶段之后,模块功能已经非常明确了,此时应该细致、清楚地编写模块功能规格说明书。原因如下:1)模块功能规格说明中描述的功能会比详细设计中更为细致和清楚。另外经过编码阶段,此时模块实现的功能可能与详细设计时考虑的模块功能在细节方面可能会有些变化。项目描述本模块的功能说明,可以方便自己和其他人日后进行系统维护工作。2)通过编写该功能规格说明可以弥补详细设计万一考虑不细情况下,一些例外和异常情况是否处没有处理或者处理不周到。由于在详细设计阶段,设计出模块的类和对象构成以及运行机制还是有一些模糊,因此很可能存在某些例外、特别分布式情况下某些状态组合没有考虑到的情况发生。但是在编码阶段,由于一般只会关注当前类和当前的方法的实现,因此考虑问题一般比较局部。为此在完成整个模块编码后,所有细节都已经明确(特别是在写代码过程中会发现存在一些新的异常情况需要处理),此时必须再一次从整体来考虑模块运行起来后在处理逻辑是否有缺陷,这样能更早发现以前设计中缺陷,避免上线后才发现缺陷。此时重点考虑是否还有情况没有考虑到或者某些处理不到位。很多BUG难以发现和定位原因是在不同类和对象之间的发生交互和联系后,组合排列后的情况非常多,从而想不到某些组合。这种BUG只有从整体考虑、考虑不同类和对象之间交互关联后才可能想到。3 模块详细设计指南与规范模块详细设计要完成两个方面工作:一是明确模块的功能需求和非功能需求、二是设计如何完成和实现模块的功能需求,包括类结构、线程结构设计等。本节根据后台模块特点,描述了两部分工作需要考虑和设计的关键点。3.1确定模块的功能规格1)本模块概述概述主要描述了本模块所属子系统,以及在子系统中所承当职责的简单描述。2)本模块在系统中与周围模块关系和交互情况很多模块一般要依赖周围的模块或者数据库,为此建议以图形方式描述本模块与本模块依赖的其他模块或者数据库之间交互情况。交互方式主要包括:基于接口调用的交互、基于数据流的交互,直接访问数据库。基于接口交互要描述:接口实现方式(ICE、WCF等)、接口调用目的、以及什么时候调用等。基于数据流交互要描述:传输数据类型,传输方式等。对数据库或者存储要描述:需要访问的数据库名称、表格名称以及表格存储数据含义、访问数据库中表格的目的等。3)本模块部署角色以及对基础软硬件要求描述本模块将要部署的角色、部署模式、对操作系统要求、对基础软件要求、对硬盘要求、对内存要求等。部署模式主要考虑是分布式多机部署、还是只会单实例部署。操作主要考虑需要对操作系统版本的要求。基础软件主要包括:jdk版本要求、需要安装其他基础软件以及版本等。对硬盘要求:是否需要临时存储、大概需要多大(尽量能不用存储就不用)。对内存要求:大概需要多大内存等。4)本模块所处理数据的数据格式描述对数据预处理模块,描述本模块对待处理数据的格式的假定和要求。5)本模块调用接口描述详细描述清楚需要调用接口:接口名字、参数类型、参数单位、接口功能、接口执行时间要求(超时处理)、分片传输(消息大小限制导致分片传输需求)。接口功能部分重点要描述清楚异常情况下接口返回值和应该执行操作,例如调用的接口是否会返回NULL等。6)本模块功能性需求描述以功能点方式详细描述本模块功能。如果是涉及对外提供接口的,明确描述:接口名字、参数类型、参数单位、各种输入参数下预期行为和返回值、接口应该满足执行时间要求。7)例外与异常情况下描述与处理要求详细考虑本模块第2)、3)、4)、5)中所描述本模块依赖的外部环境不满足本模块要求情况下的处理方式。3.2设计与实现部分1)关键问题与策略只要有一点复杂或者难度模块的设计工作都会存在几个有难度或者关键问题去解决,这些关键问题的解决方案好坏决定了整个模块实现质量。一般而言这些关键问题解决方案会有多种,并且有好有坏,且会存在较大争议。相反一般非关键点设计就比较没有异议。关键问题与策略是开展设计评审的重点。模块设计评审就是审查两点:是否存在有些关键问题没考虑到、二是每个关键问题的解决方案是否是最优的。因此要求模块设计人员,在确认了功能规格后,第一件事就是要考虑本模块设计中存在哪些关键问题,然后再思考对应解决方案。在确定了所有影响比较大的关键问题的解决方案之后,剩余的类结构设计和线程设计等就会比较顺利。此部分要求设计人员要反复问自己:一是否所有值得斟酌的问题都想到了、二目前设计的策略是否是最好的(好的策略一般是简单策略),要敢于否定自己已经设计好的策略。衡量优秀实现策略的标准是:“用最简单方式满足最重要需求”。后台设计过程中要避免的事情是:不要为了某个不常用、但是听起来很美好的功能点导致设计很复杂。有时候为了模块运行简单和稳定,宁肯不要太完美。特别是很多时候很多需求是矛盾和有冲突的,作为设计人员一定要能识别哪些是主要需求,哪些是次要需求。例如某全文检索检索模块,第一版本为提高检索性能,设计了检索结果缓存功能。但是实际使用过程中发现缓存命中概率很低,而这个功能导致整个模块设计复杂很多。2)静态类结构设计类结构设计,主要设计出本模块主要类以及类之间的关系,并利用类图的方式表达出来。在静态类结构设计中,除类图外,还需要对各个类的职责分工,以及类中主要的方法要进行描述。另外要仔细考虑哪些类是主动类。在静态类结构设计好坏,主要取决与设计人员面向对象设计的能力。要求设计人员考虑以下几个方面:是否可以采用现成的设计模式。是否违反了面向对象的几个原则:单一职责原则、开放封闭原则、替换原则、依赖倒置原则、接口隔离原则。为了提高自己此方面设计能力,希望大家多看一些面向对象设计方面的书,以及一些经典优秀开源软件的结构,能真正领会设计模式和面向对象的几个原则的精髓,并能指导自己模块类结构设计。另外如果感觉自己负责多个模块存在重复部分,例如感觉可能几个模块大的处理步骤基本相同,只是在处理细节上不同,则可以考虑将其中相同部分抽出来设计成一个具备一定通用性的框架或者共用代码,并贡献出来。3)线程结构与同步互斥策略设计后台模块一般会涉及多线程的处理,因此线程结构设计是后台组模块设计经常会遇到的问题。线程结构设计必须描述以下几个部分:包括那几类线程以及每类线程的职责每类线程的个数每类线程的启动和停止时间线程间的协作关系:消费者-生成者关系、同步互斥、共享变量等。为了清楚描述和思考同步互斥问题,建议采用图的方式划出每类线程与每类线程会访问到公共对象,这样就能很直观识别出需要保护的对象,然后在详细设计和描述同步互斥策略。线程结构设计基本经验是:尽量减少线程间的交互。例如有三类线程,本来可能需要每类之间都要交互,则可以考虑以以某类线程作为枢纽,其他两类线程都和该线程交互,而其他两类线程之间不交互。同步互斥在后台性能不是很重要情况下,可以考虑加锁的粒度粗一点。例如多个线程都要从一个队列取任务,并执行任务,且修改任务状态,则可以每次都锁整个队列,包括修改队列中某个任务的状态也变成队列类中的一个被同步保护的方法,而不是直接调用任务类的修改状态的方法。被同步互斥保护代码禁止有访问数据库、访问文件、调用远程接口等操作,必须都是只访问本地内存的操作,确保不会长期被锁住。被同步互斥保护代码只应该是“控制”代码而不能是“干活”的代码。4)主要执行流程描述本模块所需要处理的主要业务事件对应的处理过程。建议多采用泳道图来表示,好处是能直观的看到各类在该业务处理过程中的职责,方便设计人员对类的职责进行调整。5)模块配置项设计模块配置项设计主要为提高模块通用性,减少模块修改,让设计人员多考虑将很多参数作为配置而不要写死。对于配置项考虑:哪些配置项是全局配置、哪些配置项只是本模块需要读的。哪些配置项和建设方案有关、哪些配置项和建设方案无关。对全局配置项和与建设方案有关的配置项,应该放入到系统配置中去。方便系统部署时,可以实现设备安装与建设方案无关,实现设备安装程序标准化。3.3与应用运维相关的考虑为了与即将实现的应用运维系统进行对接。每个模块在设计时要考虑两个方面问题:一是如何从模块外面对模块运行状态进行监控,以及判断模块是否正常运行的标准是什么;二是如果是因为外部环境无法满足本模块要求,则在日志里面表达清楚。4 代码编程指南与过程规范强烈建议采用测试驱动的模式来完成代码编程。测试驱动开发中编写测试代码目的是利用测试代码来描述和确认类的功能规格,然后编写实现代码来实现测试代码规定的功能规格并利用测试来验证编写的代码确实是符合事先设计好的功能规格。根据前面的阐述,在详细设计时是不可能把每个类设计的很细,也就是每个类很细致的功能规格是没有设计好的。此部分工作是留在代码编写阶段来完成的,即在代码编写阶段包括:类功能规格设计和实现。大部分开发者在编码时其实是在一边在编码实现、一边在确定类和方法的功能规格,并且会不断的调整(有时候会因为突然想到一种以前没考虑到的情况没处理、有时候是为了代码实现简单等等)。此时由于大部分精力是在考虑实现,并且是局部的实现,很容易导致某些需要全局考虑的一些例外或者异常情况没有考虑到,从而出现BUG。通过测试驱动模式可以强制大家把第二部分所讲的两个阶段区分开。4.1代码编写建议采取以下步骤写代码前,先站在使用者角度考虑清楚将要实现的类功能规格。类分为高层类和低层类(例如数据库连接池代码,数据库连接池类属于高层类、数据库连接类属于低层类)。一般情况下会出现一个高层类和多个低层类组成一个内聚的包。在这种情况下,可以先写出整个包或者高层类的功能职责,然后逐步下低层的,也可以先写低层再写上层,具体过程看大家自己。因此不管怎么样,都会出现类职责调整的情况发生。编写类名和类中间的方法,但是不实现。以注释方式,描述类的职责、本类一些关键或者复杂的策略(方便别人能读懂你的代码)、本类需要处理的情况(要求从设计上,每个类职责要单一,否则这里就会写的很复杂)。以注释方式,详细描述public方法功能规格,特别是各种异常和例外情况下的处理方式(此时还没有私有方法,类的职责是通过public方法来体现的)。根据上述注释,以类为单位编写测试代码。实现各个方法,并通过测试。4.2对于编写测试代码的建议如下必须先写测试代码尽可能的去写测试代码要以类的使用者角度来编写测试代码。针对类的功能点来写测试代码,而不是针对方法不要采取为每个Public方法编写一个测试方法的模式来编写测试方法。每个测试方法应该测试的是该类需要处理的某一种情况。因为类的一个功能点可能要涉及多个Public方法。类似软件测试每个测试用例,都对应一个测试点一样。每个测试方法其实都是测试类的一个功能点。例如:一个队列类,有pop和push两个public 方法。则不要写两个测试代码:一个是testPop,一个是testPush。而是要站在使用者角度来考虑队列类的功能规格:1) 如果队列为空,则弹出空对象。2) 队列应该保证先进后出。3) 如果队列满,则Push失败。然后针对以上三种情况,分别对应写出三个测试函数。5 模块功能说明编写规范5.1编写模块功能说明的目的l编写完整个模块后,从模块整体思考和检查所实现的模块是否符合设计要求,以及在相应细节处理方面是否存在BUG,或者不合理的情况。l方便开发人员和维护人员日后的维护5.2功能说明内容及规范编写功能说明时,由开发人员站在使用者角度来描述和重新审查模块1、模块部署环境和与周围模块交互情况描述u以图方式描述本模块与周围模块的交互情况,以及部署方式。u本模块调用的外部接口描述。u本模块对基础环境要求:内存、网络、磁盘等。2、模块配置说明u配置文件设计理由,那些固定不变的,哪些是应对业务变化。u仔细描述各个配置文件的含义u说明如何通过配置来对应业务变化3、模块功能说明详细描述本模块的功能点。对每个功能点,一般描述以下几个方面:u功能名u与该功能相关的配置文件中的配置项u处理流程u故障处理u可能存在的问题。例如:功能N:按比例删除老数据相关参数STORE_POLICY:各数据类型的存储比例PARTITION_MIN_FREESIZE_GB:每个分区应该保留的剩余空间DELETE_INTERVAL_MINUTE:老数据覆盖的触发间隔。处理流程1)判断是否所有磁盘分区的数据块都被扫描,如果存在退出2)判断是否获取了所有磁盘分
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 新苏教版数学二年级下册第三单元《认识方向》测试卷(含答案)
- 远程指导下狗狗骨盆骨折家庭护理要点
- 老年人腰疼护理安全须知与辅助器具
- 儿童睡眠障碍护理与改善课件
- 肿瘤患者化疗恶心呕吐防治护理查房
- 新生儿抚触实操:促进发育、增进亲子关系技巧
- 2025年-2026年钢轨探伤工(高级)技能理论考试参考题库【附答案】
- 2024年临汾市卫生健康委员会“市招县用”招聘医生真题
- 分娩期常见护理操作(胎心监护、产钳使用)详解
- 医学职业卫生医院家庭病床感控案例教学课件
- 监理廉洁从业课件
- HJ 25.4-2014:污染场地土壤修复技术导则
- 羽毛球规则课件
- 2025年党章党史党纪知识竞赛试题库及答案
- 就业帮扶车间培训课件
- 森林扑灭火课件
- 护理专业求职综合展示
- 眼睛和皮肤光辐射最大允许照射量、产品光辐射危害风险专业分类及其可达发射极限
- 广东省高州市全域土地综合整治项目(一期)可行性研究报告
- 根管治疗技术指南
- 医学研究生统计学课件
评论
0/150
提交评论