一、 基础概念
1、面向过程的分析方法是找到过程的起点,然后顺藤摸瓜,分析每一个部分,直至达到过程的终点。
过程中的每一部分都是过程链上不可分割的一环。
面向过程方法认为每个小系统都有着明确的开始和明确的结束,开始和结束之间有着严谨的因果关系。
2、面向对象方法将世界看作一个个相互独立的对象,相互之间并无因果关系。有了对象,就能够通过提升抽象级别来构建
更大的、更复杂的系统。将复杂工程转化为标准零部件的做法,就是一种面向对象的方法。
抽象是面向对象的精髓,抽象的好处是不论在哪一个层次上,都只需要面对有限的复杂度和有限的对象结构,
从而可以专心地了解这个层次上的对象是如何工作的。另一个重要的好处是低层次的零件更换不会影响高层次的功能。
抽象有二种方法,一种是自顶向下,另一种是自底向上。
自顶向下的方法适用于让人们从头开始认识一个事物。自底向上的方法适用于在实践中改进和提高认识。
面向对象分析方法:
(1)一切都是对象;
(2)对象都是独立的;
(3)对象都具有原子性;
(4)对象都是可抽象的;
(5)对象都有层次性;
3、UML统一建模语言定义了一些建立模型所需要的、表达某种特定含义的基本元素(用例、类等),以及这些元模型
相互之间关系的规则。 建立模型的关键就是弄明白有什么人,什么人做什么事,什么事产生什么物,中间有什么规则,
再把人、事、物之间的关系定义出来,一个模型也就基本成型了。
4、统一过程(RUP)归纳和整理了很多在实践中总结出来的软件工程的最佳实践,是一个采用了面向对象思想,
使用UML作为软件分析设计语言,并且结合了项目管理,质量保证等许多软件工程知识综合而成的一个非常完
整和庞大的软件方法。
它将软件生产分为四个阶段(先启,精化,构建,产品化)和九个核心工作流
(工作流程,业务建模,需求,分析设计,实施,测试,部署,配置与变更管理,项目管理环境)。
轻量级的敏捷(XP)方法追求在变化中用最快速的办法适应变更,用小的管理成本估障软件质量。
而统一过程则适用于大型项目,开发周期较长,需要有一个稳定的架构。
5、对于软件产品来说,最佳实践来自两个方面:一方面是技术类的,如设计模式:
另一方面是过程类的,如需求方法、分析方法、设计方法等。
6、对于设计过程来说,以下的一些工作内容加上文档说明基本上可满足大部分项目需要:
(1)确定实现语言,制定编程规范。
(2)如果使用了架构或者框架,则应当提供针对架构或框架的编程模型实例,作为编程指南和约束。
(3)为每一个软件层次进行必要的设计,一方面设计该层上所有类必须实现的接口,遵循标准等,
另一方面设计处理系统中的公共事物,例如日志、事务、异常等基础模块。
7、迭代式软件生命周期是一种演进式的软件开发方法,它将一个软件视为多次增量的结果,
每一次迭代完成该软件的一个部分,而每一个迭代可视为一个小的瀑布模型。每一次迭代都有需求、分析、设计、实施。
也就是说,每一次迭代的结果都能得到一个可运行的系统,哪怕功能是不完善的。
8、需求分析师负责决定用例的优先级;
设计师负责规划模块和代码包;
开发人员负责实现模块功能;
测试人员负责按照用例场景设计和开发测试用例。
集成员负责管理这些代码并编译和集成它们。
二、 UML核心要素
1、参与者(actor),是在系统之外与系统交互的某人或某事物。
参与者一定是直接并且主动地向系统发出动作并获得反馈的,否则就不是参与者。
(1)业务主角:是参与者的一个版型,是与业务系统有着交互的人和事物,在需求阶段使用,用来确定业务范围。
业务范围和系统范围有所不同:业务范围指这个项目所涉及的所有客户业务,这些业务有没有计算机系统参与都客观存在。
系统范围则是指软件将要实现的那些对应于业务功能的系统功能,从功能性需求来说是业务范围的一个子集,
但有时也会超出业务范围,例如操作日志。
要建设一个符合客户需要的计算机系统,首要条件是完全彻底地搞清楚客户的业务,而不是预先假设已经有了一个计算机系统,
再让客户来假想需要计算机系统帮他们做什么。
(2)业务工人:处于系统边界内,参与了业务的执行过程的某人或某事物。
如何区分是参与者还是业务工人?最直接的办法是判断是在边界之外还是边界之内。可通过以下三个问题来确认:
1)他是主动向系统发出动作的吗?
2)他有完整的业务目标吗?
3)系统是为他服务的吗
答案如果是否定的,那一定是业务工人。
2、用例:是一种把现实世界的需求捕获下来的方法。它定义了一组用例实例,其中每个用例都是系统执行的一系列操作,
一个完整的用例定义由参与者、前置条件、场景、后置条件构成。
用例的特征如下:
(1)用例是相对独立的。
(2)用例的执行结果对参与者来说是可观测的和有意义的。例:登录系统是有效用例,输入密码则不是。
(3)用例必须由一个参与者发起。
(4)用例必然是以动宾短语形式出现的。
(5)一个用例是一个需求单元、分析单元、设计单元、开发单元、测试单元、甚至部署单元。
用例粒度:
(1)在业务建模阶段,用例的粒度以每个用例能够说明一件完整的事情为宜(业务用例)。
(2)在用例分析阶段,即概念建模阶段,用例的粒度以每个用例能描述一个完整的事件流为宜。
可理解为一个用例描述一项完整业务中的一个步骤(概念用例)。
(3)在系统建模阶段,用例视角是针对计算机的,以一个用例能够描述操作者与计算机的一次完整交互为宜(系统用例)。
一般来说,一个系统的业务用例定义在多于10个,少于50个之间,否则就应该考虑一下粒度选择是否合适了。
通过以下问题引导业务代表,这些问题对用例获取来说已经足够了。
(1)您对系统有什么期望?
(2)您打算在这个系统里做些什么事情?
(3)您做这件事的目的是什么?
(4)您做完这件事希望有一个什么样的结果?
用例和功能的误区:
功能实际描述的是输入->计算->输出,把用例当作功能点的做法实际是在做面向过程的分析。
在描述一个事物的时候,可以从以下三个观点出发:
(1)这个事物是什么?(结构性观点)
(2)这个事物能做什么?(功能性观点)
(3)人们能够用这个事物做什么?(使用者观点)
软件是一种还不存在的事物,对于正准备开发的软件,不能从结构观点去描述它,也不能从功能观点去描述它,
最好的方法是从使用者的观点去描述它。
3、边界
边界是用于划分系统与其他系统,特别是相邻系统关系的一种方法;
边界应该能说明那些元素是属于本系统的,那些元素不是本系统的,是属于系统外部环境的;
边界的划分除了能界定本系统的元素外,还应能界定与表示本系统对外的输入与输出,即本系统与环境的关系。
边界是虚幻的,又是必不可少的,能否准确把握边界,能否灵活变换边界,能否控制边界的粒度是做好需求分析
和系统设计的关键。
通过设定边界,组织边界大小来决定抽象层次,例如对于汽车的描述:
(1)如果设定边界是整辆汽车,观察到的是汽车的大小、颜色、质地等东西。
(2)如果设定边界在汽车内部,观察到的是方向盘、仪表盘、中控板这些东西。
(3)如果设定边界在仪盘盘内部,观察到的是指示盘、电路、齿轮这些东西。
通过自顶向下的方式,逐步缩小边界决定我们的抽象层次,使得我们的分析粒度可以有条不紊地逐步细化。
也可以采用自底向上的方式来提高我们的抽象层次。
注:一个好的分析和设计如同一筐带壳的鸡蛋,清清爽爽;一个差的设计如同一堆打碎了壳的鸡蛋,粘粘糊糊。
4、业务实体
业务实体代表业务角色执行业务用例时所处理或使用的“事物”。
一个业务实体经常代表某个对多个业务用例或用例实例有价值的实物。
它作为类的一个版型,具有对象的所有性质,包括属性和方法。
获取业务实体的方法:
(1) 首先建立业务用例场景。
(2) 然后从业务用例场景中逐个分析动词后面的名词,它们就是业务实体的备选对象。
(3) 分析这些业务实体之间的关系,并决定哪些应当单独建模,哪些应当作为属性。
5、包
包如同文件夹一样,将某些信息分类,形成逻辑单元。主要作用是容纳并为其它元素分类。
分包具有以下一些指导性原则:
(1)被分入同一个包中的那些元素应当是相互联系紧密,甚至不可分割的。
(2)修改A、B、C三个包中任意一个包的元素,其他的任何一个包中的内容都不受到影响。
(3)至少保证包之间的依赖关系不会被传递。
(4)包之间的依赖关系应当是单向的,应当尽量避免双向依赖和循环依赖。
6、分析类
分析类用于获取系统中主要的“职责簇”。它们代表系统的原型类,是系统必须处理的主要抽象概念的“第一个关口”。
它是从业务需求向系统设计转化过程中最主要的元素,高层次抽象出系统实现业务需求的原型,业务需求通过分析类被逻辑化,
成为可以被计算机理解的语义。
主要有以下三种:
(1)边界类,用于对系统外部环境与其内部运作之间的交互进行建模的类。
(2)控制类,用于对一个或几个用例所特有的控制行为进行建模。
(3)实体类,用于对必须存储的信息和相关行为建模的类。
7、设计类
设计类是系统实施中一个或多个对象的抽象,设计类所对应的对象取决于实施语言,
它可以非常容易和自然地从分析类中演化出来。
设计类由类型、属性和方法构成。设计类的名称、属性和方法也直接映射到编码中相应的class、property和method。
8、组件
组件是系统中实际存在的可更换部分,它实现特定的功能,符合一套接口标准并实现一组接口。
组件具有以下特性:
(1)完备性:组件包含一些类和接口,一个组件应当能够完成一项或一组特定的业务目标(或说功能)。
(2)独立性:组件应当是可以独立部署的,与其它组件无依赖关系,最多仅保持关联关系。
(3)逻辑性:组件是从软件构件设计的观点来定义的,并非从需求中可以直接导出。
(4)透明性:组件的修改应当只涉及组件的定义以及组件中所包含的类的重新指定,而不应当导致类的修改。
组件的应用场景:
(1)分布式应用:在分布式应用的情况下,系统的功能可能被部署在异构环境下,一个业务目标可能需要经历两个甚至多个节点才能完成。
(2)应用集成:在应用集成项目中,新业务要调用遗留系统的功能,但是又不能修改遗留系统,
一个解决方案就是在新系统中规划出一些组件,这些组件所拥有的接口完成遗留系统的功能。
(3)第三方系统:第三方系统要访问本系统时,将本系统要提供给第三方系统使用的功能定义成一系列组件,
让第三方系统通过组件访问本系统,而不应该把本系统的类直接暴露给第三方系统。
(4)服务:SOA服务将系统结构划分为粗粒度的服务组件SCA,每个服务组件都遵循一系列的标准和规范,
通过标准的通信协议与其它服务交互。
三、其它设计理念
1、用例是系统思维
系统思维就是考虑系统内事物的互相影响而不是观察单个事物的变化,归纳、抽象系统内的运行规律而不是研究单个点的存在意义。功能孤立地存在并无意义,只有将使用者与功能交互系统地看待,软件功能才有意义。
(1)线性思维下的系统分析设计结果
(2)系统思维下的分析设计结果
2、用例是面向服务的
(1)SOA的第一条准则便是:业务驱动服务,服务驱动技术。第一,业务和技术不再是两个可以分离的领域,并且技术由业务决定。
第二,业务和技术之间需要一个桥梁,这个桥梁就是服务。
(2)SOA服务是由SCA组件来代表的,一个基本的SCA组件包含服务定义、服务流程和服务数据。
SOA最大的成就不是创造了开放、包容性强、灵活、敏捷的技术架构,而是超越了技术架构本身,在其之上提出了一种全新的软件理念。
这个理念脱离了具体技术的束缚,用服务而不是技术来架构一个软件系统。
3、建模的抽象层次
(1)自顶向下
自顶向下的方法是试图发现事物的本质内更为具体的性质,从中找出共性的过程。例如小汽车和大卡车用自顶向下的方法抽象,能够发现两者都有轮胎、发动机、方向盘。
(2)自底向上
自底向上的方法是试图发现事物本质以外更为概念化的性质,例如用途、行为等。
例如小汽车和大卡车用自底向上的方法抽象,可抽象出它们的外在性质,可载货物、可开动等。
对软件分析来说,从需求开始、分析、设计到实现的过程是采用自顶向下方法的;而每一步分析结果出来以后,归纳和总结获得的结果,采用自顶向上的方法优化和更深一步了解这些结果。
从代码到类,从类到组件,从组件到框架,从框架到架构,这是不断提升的抽象层次。当前代表最新抽象层次的就是SOA。
4、边界是面向对象的保障
(1)API或SPI实质上就是对象的边界,任何其它对象试图访问该对象时,必须经过边界并且遵守边界的约束(可访问哪
些方法)。一旦习惯了在任何时候都从边界出发来看待对象世界,也就习惯了封装和面向接口设计。
(2)边界分析最大的意义在于,如果读者时时心中存有边界的概念,知道不论用例也好,领域类也好,都被边界包裹着,
它们之间的交互只应当通过边界进行,并且不能交叉,就能设计出更完美的面向对象设计。
举例:图书馆业务,可以将读者和图书馆分为两个边界。读者边界封装读者的所有信息和行为,图书馆边界封装图书馆的所有信息和行为。
5、接口是系统的灵魂
(1)要定义一个系统,真正需要了解的是组成系统的对象表现出来的样子以及它们之间的交互行为,而不是孤立地谈论
单个对象。人们认知现实世界和认识软件的过程是一致的,是从接口(表象)来认知对象而不是从对象内部(本质)
来认知对象的。越是本质的东西对理解来说越“抽象”,相反越是表象的东西越容易理解。
(2)可以简单地认为每个边界就是一个接口,这个接口有着属性和行为,这是它所表现出来的样子。
这些属性和行为支撑起整个系统大厦, 而对象内部的实现可以改变,可以替换,却无法影响整个系统大厦,
就像不论怎样装 修内部房间,也不可能改变整栋大楼的结构。