以为有银弹;按指南步骤去做(滋生进度谎言);完全忽略文档,或文档驱动。
成功的软件项目:提交产物满足或超出客户预期,开发过程符合时间和费用上的要求,结果在面对变化和调整时有弹性。成功项目的特征:
1. 很强的架构愿景
架构:系统的基本组织结构,包括它的组件、组件之间的相互关系、环境,以及设计和演进的指导原则
架构关注结构和行为,只关注重要的决定。
概念完整性是系统设计中最重要的考虑。
好的软件架构的一些共性:
敏捷过程倾向于降低早期建立架构的重要性,简单设计、突发设计、重构和“偶然发现的架构”等,架构随时间演进。
但是架构在生命周期何时完成,都不会降低拥有架构愿景的重要性。
2. 迭代和增量式开发生命周期
以连续系列的发布版本(迭代)的方式开发系统的功能,完成度不断增加(增量)。
发布版本可以是外部的(提供给客户),也可以是内部的(不提供给客户)。
实现功能按照风险排序,最重要风险先处理。
当组织机构承担了很多项目时,拥有一个标准过程是有好处的,如果达成一致,更容易测量项目的进度。
管理良好的迭代增量式生命周期,其中管理良好是指过程可控并可测,有不至于太严格,不会丧失鼓励创造和创新所需要的自由度。
可选开发过程:RUP,XP,SCRUM,Crystal等
敏捷过程 |
计划过程 |
目标:短时间内向客户提交满足需求的系统 |
除提交系统外,还要定义和验证一个可预测可重复的开发过程 |
轻量级、松散式、不太正式(只做绝对需要做的事情) |
较重量级、较正式(按照规定的活动得到文档齐全的工件) |
依赖于团队成员的隐式知识(而不是有良好文档的过程) |
依赖于有良好文档的过程(而不是隐式知识) |
关注战术超过关注战略(不要为将来而构建,因为将来是不可知的) |
关注战略超过关注战术(建立起强大的架构框架,可以包容将来的变化) |
严重依赖与客户的协作(团队想出最好的工作方式) |
受管理的、受控制的(遵守详细的计划,无论团队内还是团队间都包括明确的里程碑和验证点) |
突发式而不是预先确定(在实际执行过程中让过程演进,而不是事先计划或确定) |
事先定义然后持续改进(包括明确的过程改进流程和机制) |
项目小(5-10人) |
项目大(超过10人) |
有经验的团队,具有各种能力和技术 |
团队包括不同的能力和技术 |
团队成员是自我驱动的,独立的领导者及其他自己知道方向的人 |
团队是地理上分散或外包的 |
项目是内部项目,团队在相同的地理位置 |
项目具有战略重要性(例如是一个企业首创的)范围跨越整个组织机构 |
系统是新的,充满了未知数 |
系统已被充分理解,具有熟悉的范围和功能 |
需求必须是已被发现的 |
需求相当稳定(变化的可能性小)能够实现确定 |
需求和环境是易变的,变化的可能性很大 |
系统大而复杂,具有关键安全需求或搞可靠性需求 |
最终用户的环境是灵活的 |
项目涉众与开发团队之间的关系一般 |
与客户的关系密切,有很好的合作 |
存在外部合法性考虑(如合约、义务、针对具体行业标准的正式认证) |
客户随时可以找到,全职投入且在同一地理位置 |
重点是强大的、量化的过程改进 |
在开发团队内部、开发团队之间、开发团队和顾客之间存在高度信任的环境 |
重视过程的定义和管理 |
需要快速价值和快速响应 |
重视过程的可预测性和稳定性 |
随着开发生命周期中发现的问题,应该优化过程(理想情况是在每次迭代之后)。根据过程执行的实际经验对过程进行持续改进应该是我们的目标。
宏观过程是总体的软件开发生命周期,它是微观过程的控制框架。
宏观过程规定了一些可测量的产物和活动,让开发团队能够有意义地评估风险,并尽早对微观过程进行调整,以便更好地关注团队的分析设计活动。
《面向对象分析与设计》一书中描述的宏观过程是RUP生命周期。
宏观过程的目的是知道系统的整体开发,最终得到产品系统。宏观过程的范围从确定想法开始,直到实现该想法的第一个软件系统版本为止。
移交之后软件的演进和维护
|
包括以下科目:需求、分析和设计、实现、测试、部署
在生命周期中将执行下列科目:
一些基本实践:需求管理、配置管理、测试和品质保证、代码走查以及编写文档
原型:目的是快速探索可选的设计,可以尽早解决某些风险。原型不应该直接发展成为产品系统,除非有非常好的理由 |
瀑布与迭代的里程碑的差别
1. 初始
目标:关注于确保业务价值和技术可行性。确定对想法的愿景并验证它的假定。
活动:建立系统的核心需求并排除优先级,理解风险,决定开发环境(过程与工具)
工作产品:构建系统的愿景、行为原型、初始风险列表、确定的关键架构机制及开发环境
里程碑:范围已理解 系统总体范围和关键需求清楚理解后,初始阶段就完成了。客户和开发组织对系统的范围和总体交付时间表也达成一致。
2. 细化
目标:尽早确定架构的缺陷,建立起一些通用的策略,以得到一个更简单的架构,这个形成过程是通过缓和最大风险、实现最高优先级的需求和实现架构最重要的部分来驱动的
活动:制定架构方面的决定、建立架构框架、实现该框架、测试该框架,根据测试结果优化框架。架构的演进就是努力满足一些相互竞争的约束条件,包括功能、时间和空间
工作产品:架构文档外,创建一系列可执行的架构发布版本,成为演进产品系统的基础
里程碑:架构已稳定 对所有关键系统需求进行了验证,且所有风险得到了适当缓和,能够预期系统开发完成的费用和时间进度。一个关键标志是关键架构接口和机制的变化率已大大降低或完全消除。
3. 构造
目标: 可部署产品的生产。一个受控的方法学过程,将产品品质提升到可发布的水平
活动: 完成系统的开发
工作产品:可执行的发布版本,演进为产品系统
里程碑: 系统已准备好进行最终用户测试功能和品质足以部署给最终用户进行测试。评价标准有发布版本的需求满足度、发布版本的品质。品质的一个标志就是缺陷发现率。
4. 移交
目标: 确保软件被它的最终用户接受
活动: 提供给用户进行评估和测试。产品调优,处理配置、安装和易用性问题,处理早期使用者提出的问题。支持文档、培训材料;包装和市场宣传材料;验收测试
工作产品:包装好的产品、所有的支持文档、培训材料和市场宣传材料
里程碑:系统已准备好进行部署 功能和品质足以提供给最终用户(通过验收测试);首要评判标准和构造阶段类似,即缺陷率下降(早期试用者报告)
|
|
输入:待构建系统的范围,所有限制因素(费用、时间、品质)
活动:建立项目的开发节奏,排列需求的优先次序,将需求分配到各次迭代中
确定迭代的发布版本是外部发布还是内部,最后制定详细的迭代计划
结果:一份开发计划,确定一系列的发布版本、团队活动和风险评估
第一步,建立项目的开发节奏——决定迭代的平均时间(发布版本的时间间隔)
下一步,确定需求的优先级(功能、非功能);排序因素(对涉众好处、对架构影响、将缓解的风险)
每个迭代应该有一个计划好的效果,清晰的评估标准,用于评估迭代是否成功
开发早期,通常内部发布;交给品质保证人员测试;后期以受控的方式交给最终用户。
所谓受控是指为版本设定期望值,并确定希望评估哪些方面。
更多内部(系统的一种持续集成),少数可执行的发布版本提交给外部
最后一项,制定详细的迭代计划,确定关键里程碑,建议迭代数目及高层理解
微观过程使用了宏观过程提供的需求,产生了设计规格说明(架构),然后在宏观过程中实现、测试并部署。
分析的目的是提供一个系统行为的模型。
分析关注的是行为,而不是形式。说明系统做什么,而不是如何做(在系统分析时做)
当得到了关于系统行为较为完整的模型时,就可以开始设计过程了(避免不成熟设计)
避免延迟设计:进行彻底讨论,试图得到完美分析模型,因此无法实现
架构主要考虑的时系统各部分(即组件)之间的关系,以及它们的职责、接口和协作。
系统组件的分析和设计关注的是这些组建的内部,以及它们如何满足(架构的)需求。
|
科目:分析 |
设计 |
考虑:架构上 |
关注:建立初始的系统架构框架,为架构设计提供指导和上下文背景 |
关注:优化架构分析得到的架构,确定系统主要的设计元素,包括必须遵守的共同机制 |
组件 |
关注:理解当前的一组需求。提供解决方案的初始版本,将需求分配到解决方案的元素中去 |
关注:改进设计元素,得到一份规格说明。这份说明可以利用具体的实现技术有效地实现 |
确定元素:发现或发明元素,确定OO分解
确定协作:描述已确定元素间如何协作以提供系统行为需求
确定关系:确定元素间关系,以支持系统的协作
确定语义:确定元素的行为和属性,为下一个层次的抽象准备元素
架构描述:描述了系统的架构,包括对通用机制的描述。
分析设计模型:软件解决方案中的分析和设计元素、它们的组织方式以及实现。
AD的好处:维护一个AD模型有助于建立一个共同词汇表
系统中元素的集成存放可将其作为一种载体进行查看,有助于新成员理解系统
让架构师能够全面了解项目,从而发现共同之处
其他:MDA(模型驱动架构)
用文档记录软件架构:4+1视图(需求、逻辑、实现、进程、部署)
2. 步骤
在分析过程中,设计者与领域专家合作,识别元素,发现抽象,研究问题域发现分析元素
在设计过程中,架构师和设计者一起识别元素,从解决方案出发,创造出新的设计元素
分析多为发现,设计多为发明
识别元素:
对各抽象层,方法总体一致;
识别重复递归进行,发明更细粒度抽象,发现已有抽象的共性;
将分析元素细化为设计元素:
具有一组重要职责的分析类
应该一起维护的信息的分析类
协作提供特定或相关行为需求的分析类
具有相同职责或相关责任的
3. 里程碑和判断标准
在特定的抽象层,针对特定的范围,如果得到了一组足够的抽象,一致地加以命名和描述
评判:在特定的抽象层,针对特定的范围,是否得到了足够稳定的AD模型。即在每次完成微观过程迭代后,模型没有大量的改动。
1. 产品
主要产品是一些实现,它们说明了已被识别的元素如何协同以提供某个范围内的行为需求
这些实现描述了一组行为需求是如何通过处于某个抽象层上的元素协作来实现的
实现反映了协作元素之间明确的责任分配,并在需求和软件解决方案间架起桥梁
实现最初用分析元素来描述,后来以设计元素来描述
实现及支持的元素责任通过AD模型被记录在文档中。
分析过程中,通常一个短语或一句话;
设计过程中,为每个元素创建规格说明,如操作名称,操作构成元素的协议
详细设计中,操作以接口的方式正式记录,包含用实现语言写下方法签名
用UML交互图(序列、通信)、状态机图来表现。
2. 步骤
1)行为分析,将责任分配给元素(考虑异常和预期)
(1)从行为需求中选择一个或一组场景
(2)确定与该场景相关的元素
(3)推演场景,责任分配到元素
(4)重新分配责任,使之更平衡
(5)考虑并发和分布
* 状态机图的应用
2)在实现中提取模型,使之更抽象更一般
(1)针对该抽象层次,寻找元素间的交互模式
(2)针对所有责任,寻找行为的模式
(3)如果在较低抽象层,寻找操作签名中的模式
* 消除重复,提取共性
3. 里程碑和判断标准
得到了一组一致的元素和责任,在某个抽象层次上,在一定范围内提供了系统要求的功能行为,并且做到了在这些元素之间进行有意义的、平衡的责任分配
检查点:
1. 产品
确定每个元素的边界,清楚地表达哪些元素之间互相协作
这项活动正式确定了元素之间的分离关注,最初是在确定协作时建立的
2. 步骤
1)识别关联:初步识别元素之间的语义联系
(1)收集一组元素,处于某个抽象层,或与特定的场景、实现有关系
(2)考虑任意两个元素间是否存在关系,建立关联
(3)针对关联,如角色和元素名不同,指定角色;多重性、约束(不要过度,为细化的任务)
(4)走查场景来验证,确保关联是必要和足够的
2)细化关联:成为语义上更丰富的关系
(1)寻找一组关联联系在一起的元素,将关联细化为依赖、聚合、组合
(2)寻找元素之间的结构模式。如有,考虑创建新元素,引入继承
(3)寻找元素之间的行为模式。如有,考虑引入共同的参数化元素,执行共同的行为
(4)考虑已有关联的导航型,如有,对导航加以约束(单向,双向)
(5)随着开发的进行,引入一些细节,如角色、多重性等
3. 里程碑和判断标准
在某个抽象层次指定了元素之间的关系。注意参与实现的元素关系的一致性。
评判标准:内聚、耦合和完整性
1. 产品
细化的AD模型。包含了元素的详细语义。
分析时,利用活动图的方式描述职责和总体流程;状态机图来描述元素协议的动态语义
设计时,DD后期,为具体操作命名;指明应该使用的算法;与实现语言绑定,包含伪代码或可执行代码;得到类接口后,开始利用编程工具测试和确保实现它们。
2. 步骤
(1)列出元素的角色和职责。通过查看所有调用该元素的协作来确定其职责
(2)更详细描述职责。绘制整体流程的活动图或序列图,状态机图等
为每项职责、操作推荐算法;考虑引入辅助操作(算法分解为简单可复用部分);
考虑存储元素状态还是计算元素状态
(3)考虑继承。选择合适的抽象类,调整继承关系。
如果元素语义不能通过继承、实例化或委托来提供,请考虑在下一个抽象层次中提供一种合适的表示形式(如果正处于设计层,这可能包括实现语言提供的原语)
从客户的角度来看操作;
(4)为元素定义职责时,考虑该元素为实现其职责而必须具备的属性
(5)设计一组足够的操作,来实现职责;如可能,尝试复用概念上类似的角色和职责;
作为单个类,职责是有该类的操作记录的;
作为组件,职责是由组件提供的服务来表现,通过组件接口的操作来记录
3. 里程碑和判断标准
对处于特定抽象层次的元素的语义有了更完整的理解(提供了足够的细节,以便更够进入下一个层次的抽象),并且为这些元素指定的语言在这个抽象层次上是一致的。
目标:得到一组清晰的抽象,具有高内聚、低耦合的特点
在分析时,得到了分析元素的职责和属性描述,了解的东西足以让你进入设计即可
在设计时,得到了更准确的语义(操作和属性),足够进入实现和测试即可
评价:简单性