《Thinking in UML》学习总结
@(总结)[思考|学习|记录]
@[toc]
简要
最近看完了这本书,感觉还是很有内容的,从面向过程到面向对象,从现实世界到计算机软件,不仅讲述了方法,同时还带给我一种做软件的思想,当我有了这种思想后,也常常会用到生活的其他领域中,比如边界这种思想。总而言之,这本书值得一看,而且还得多看几遍才能明白其中的方方面面。
面向过程和面向对象
面向过程和面向对象都是是对世界的认识方式,只是角度不一样。
面向过程
- 定义: 面向过程认为世界是由一个个关联的小系统构成,这些小系统有着明确的开始和结束,而且开始和结束之间有着严谨的因果关系,既然如此,当我们分析出小系统的每个步骤和影响这个系统的走向的因素,就可以完全定义这个系统。
- 分析方法: 找到开始,然后顺藤摸瓜,分析每一个步骤,直到结束。每一个步骤都是不可或缺的。这种方法在我们学习一个东西的时候会经常用到。
- 缺点: 本身蕴含着一个前提假设,就是这个系统是稳定的,所有的工作成果都依赖于这个过程的步步分析。看看这个定义和方法,就可以看到如果要分析的东西很复杂,逻辑很乱的话,要去顺藤摸瓜,一步一步去分析,是很困难的。
面向对象
- 定义: 面向对象认为世界是由一个个相互独立的对象组成,这些对象之间并无因果关系,只有在某个外部力量作用下,这些对象才会依据某种规律相互传递信息,这些交互构成了生动世界的一个“过程”。
- 分析方法: 通过uml建模来分析。
-
缺点: 现实世界和对象世界存在差距,这个差距很难跨越,如果需要跨过这道鸿沟,就需要解决三个问题:如何从现实世界映射到对象世界?如何在对象世界中描述现实世界?如何验证对象世界是否正确描述了现实世界?
建模公式
- 问题领域是由多个抽象角度组合的,比如筷子和勺子的区别是什么?就可以从形状、用途等抽象角度去分析这个问题。就不用去全盘考虑一个问题,全盘考虑不仅考虑了事物,也把事物之间的关系也考虑进去了,所以会不断地在做平衡。而从多个抽象角度去分析,就是把问题领域分成多个细小的问题,最后组合起来就可以了,它是先考虑事物,然后再来考虑关系,这样会比较轻松点。
- 人、事、物、规则在建模过程中是常见的,这也是去模拟现实世界,在什么条件下要达到什么目的,看起来比较简单的事。
用例驱动
- 软件的开发可以通过用例来驱动,用例是一个抽象的结果,也就是问题领域的一个描述角度,要解决一个问题,只要找到这个问题领域的所有必要的用例就相当于近似找到了这个问题的解,也就是从过个角度去描述问题,从多个角度去抽象问题。
- 当找到了用例后,要做的就是实现这个用例,也就是为这个用例提供用例场景,在确定用例场景的过程中,可以找到要实现这个用例所需要的人、事、物、规则,如果找到了,那么问题的一个抽象角度就完成了,这个问题就解决了一部分,不考虑设计的话,应该就可以直接编码了,现在开发java web应用有mvc的模式,正好对应着这四要素:人->发请求的用户,事->view,视图层,这个视图层不是纯粹的几张页面啊,而是相对于用户来说,看到的一个应用的整体,只不过实际能看到的只是用户交互的页面,所以视图层可以当做是应用的边界,物->model层,就是实体了,规则->controller层,就是控制层了;这些确定后呢,以目前的工作经验来说,就可以实现功能了。
- 当对每个用例都实现后,就会产生很多这样的人、事、物、规则,为了代码的规范呢,就会对这些元素合并的合并,删除的删除,拆分的拆分,但是用例还是不变。
抽象层次
- 抽象层次越高的东西,就越容易理解和处理,因为屏蔽的信息越多,信息量越少。并不是越具体的东西越容易理解,具体事物如树叶、手机,要具体描述一片树叶是不是要用专业的生物学术语,由什么细胞组成、叶绿素、表皮组织等等,一般人看到这样的描述是云里雾里的,还不如说这片叶子颜色是什么,形状如何等等,这些描述也要用抽象的词语去描述才行,不能把颜色说成是由红黄绿三种颜色按什么比例去组合,谁知道组合后是什么颜色,我们的大脑又不是机器能记住这么多组合,只能说红色,然后就会想到,像五星红旗那种颜色,这样就可以理解了。
- 抽象有两种方法,一种是自顶向下,一种是自底向上。自顶向下适合从头开始了解一个新的事物,自底向上适合在实践中去改进事物。在软件开发中,主体应该采用自顶向下的方法,开始用少量的概念去覆盖需求,再逐步降低抽象层次,直到编码。同时辅以自底向上的方法,通过总结在较低抽象层次的实践经验来改进较高层次的概念来提升软件质量。
- 那么建模过程中,应该在什么时候选择什么样的抽象层次,以及总共要抽象多少层次,也就是说用例要选择一个怎样的粒度,这是一个问题。
视图
- 首先视图是用来干什么的需要知道,建模的目的是为了向软件相关人展示将要生产的软件产品,通过什么来展示呢,视图是一个很好的方法,不同的视图可以展示软件的不同方面,静态的、动态的、结构性的、逻辑性的等等,然后uml建模中就有对应的用例图、对象图、类图、包图、活动图等。
- 在给软件相关人展示软件的方方面面时,需要注意选择的视角是否合适,也就是被展示的人在他的所处环境中是否看到了他应该看到的东西,也就是视角要选对,比如针对业务员,他可能只关心表单的填写,对经理,他会关心整个业务的流程,对程序员,他关心业务的流程和类的设计。
对象分析的方法
- 独立性。对象之间是互相独立的。对象是在实现用例,也就是在确定用例场景时找到的,但是找到的一切有名字的事物,也就是对象,它们都不应该是和这个场景绑定的,换句话说,对象是离散的,即使是这个场景中得到的,也不过是对象在这个场景的映射(这让我想到线性空间里映射),所以在建模过程中,要想深入了解对象,就需要分析很多该对象的实例参与的场景,以获得该对象的诸多侧面信息,然后通过归纳整理这些侧面信息抽象出对象的一般特性。这就是对象分析的方法。有项目经验的人在做过很多项目后,看到许多相似的对象或者函数,就会产生强烈的把它们公共化的思想,这就是抽象的原动力,当然在写代码的时候,也会有这样的想法。独立性带来的正是正是对象的可抽象能力和可扩展能力。
- 原子性。在统一抽象层次上,对象是不可再分的,所以对于各个对象的认识应该附加上在对象的边界上,而不应该去关注对象的内部细节。这就是面向接口编程。
- 抽象性。对象是可抽象的。对象是具有多个方面的,每个方面都对应着一个场景,因为对象的总是从场景中分析得来的,它在场景中肯定展现了它的一个方面。总可以将对象的某一方面抽象出来,让其作为对象的一个代表在场景中交互。通常这种抽象会以接口来命名。在spring源码中,有很多接口,各种实现错综复杂,之所以会这样那样的实现接口,就是因为设计者的思想里有这种对象是可抽象的概念,一个对象从无到有,一直实现接口,一直获得各种能力,这是对抽象性概念的应用。
- 层次性。对象是具有层次性的。层次越高,描述越粗略,适用性越广,层次越低,描述越具体,使用性也窄。这需要根据问题的复杂性来分层次,复杂的问题自然层次分的多一点才好理解。
获取需求
定义边界
-
之所以要定义边界,是因为要获取业务用例。软件刚开始时,是一团迷雾。
-
怎样定义呢?可以根据业务目标来定义。拿用电客户服务来举例:
该业务目标是“为用电客户提供业务办理自动化服务,提高办事效率,方便客户,为客户提供更好的服务”,配上这张图就可以看出业务主角是谁了,我们认为边界外面的才是业务主角,而边界内的只能算是业务工人,他们是不能提供用例的,只能是用电客户有资格提出用例,也就是提出他们的期望,用电客户希望可以办理业务和交费,那用例就是如此了,边界内的那些部门所做的事情都是为了满足这两个需求;到了这里呢,我们通过这次的边界定义获得了一个大概印象,可以为我们获取用例奠定基础。接下来再看一个边界,根据另外一个业务目标定义的,每一个业务目标都有一个边界存在。
可以看到刚刚的业务工人摇身一变成了业务主角了,然后呢,就可以在这个业务目标下获得一些用例。
业务用例必须是以达到业务主角的完整业务目标为标准,而不能以实现业务主角业务目标的步骤为标准。
发现主角
当边界后,业务主角也有了,但是呢,要实际去分析除该业务主角外是否还有隐藏的业务主角,业务主角区别于系统参与者,系统参与者是系统的实际操作者,通常都有id,而业务主角是用来分析业务的,而业务的分析界都是要与客户交流并达成共识的。因此业务主角不应当被过分地抽象化和虚拟化,应当能能够映射到现实业务中的工作岗位设置、工作职责说明等,并且使用客户习惯的业务术语来命名。
获取业务用例
边界定义好了,业务主角找好了,就是获取业务用例的时候了,该怎么获取呢?可以从岗位手册、业务流程指南、职务说明等一些文件获得,还有一种很重要的方法,就是业务主角访谈。通常可以问如下问题:
- 您对系统有什么期望?
- 您打算在这个系统里做些什么事情?
- 您做这件事的目的是什么?
-
您做完这件事希望有一个什么样的结果?
在定义边界时,可以看到业务主角的业务目标,从目标上看只能得到一个大概的用例,然而业务主角需要做什么具体的事情并不清楚,这就要通过各种方式去寻找业务具体想做的事情是什么。
业务建模
一个完整的业务模型包括:
- 业务用例视图
- 业务用例场景
- 业务用例规约
- 业务规则
- 业务对象模型
- 业务用例实现视图
- 业务用例实现场景
- 包图
当然在实际开发中,并不要做这么全面,只要能做到理解业务就可以了。
业务用例场景
场景是说某个业务用例的实际实现过程,包括涉及的步骤、经过哪些角色处理、出现问题怎么办等等。
业务用例的视图之前说过,但是业务用例场景的视图怎么表示呢?
有三种:
- 活动图
- 时序图
-
协作图
如果想强调参与该业务的各参与者的职责和活动,可以选择活动图;如果想强调该业务的完成时间顺序,并且在完成的过程中传递的信息是什么,可以选择时序图;如果想强调参与该业务的各参与者之间的交互过程,可以选择协作图。
业务用例规约
规约是对场景视图的文字描述,其中的过程描述可以认为是活动图的文字版,因为文字描述来得严谨,所以用例规约还是必要的,宁可省略活动图,也不要去省略用例规约,不然看着图去开发,理解会有不同,不如白纸黑字写的清楚。
业务规则
如果业务规则只用于一个用例,直接写在规约里就可以,如果用于多个用例,就要编写专门的业务规则文档。
业务对象模型
业务对象模型就是对业务场景中涉及到的一些业务实体建模。
业务用例实现视图
一个业务用例可能有不同的实现,也就是有不同的场景,即实现方式不同。如:
一般一个业务用例实现对应着一个业务用例场景。
业务用例实现场景
业务用例实现场景的建模方式和业务用例场景的建模方式有点差别。用例场景着重表示业务是怎样执行的,并没有去描述这些执行步骤是如何实现的,而用例实现场景就是着重描述步骤是如何实现的,是如何通过人机交互来完成业务的。
如果说业务用例场景是跟客户就业务达成共识,那么业务用例实现场景就是跟客户就如何操作达成共识。
包图
包是用来分类元素的。业务建模中,包图更多用于信息分类。例如将业务用例分类,将参与者分类,因此更多地采用领域包的版型,领域包就是根据业务的不同来定义的一种分包方式。
但是分包还有按业务部门分、按业务过程分等等。
领域模型
- 首先解释下领域是什么意思。
在解决问题的时候,我们通常会分解一个大问题,得到很多个小问题,而这些小问题是相互独立的,那么每个小问题是可以叫做一个领域的。
- 它和业务用例模型有什么区别呢?
在建模的方式上,还是有很所不同的,业务用例建模针对的是业务目标来建模,确定一个业务用例是从人做事的角度,说明一个业务目标是由哪些人做哪些事来构成的;领域建模是针对一个整体提出许多关心的问题,再针对每个问题求解。这些问题不会覆盖所有的业务范围,相互之间也没什么因果关系。
- 为什么需要领域模型呢?
首先,用例分析方法是有缺陷的,它能很好地说一个系统的功能性需求,从什么人做什么事的角度来将系统定义清楚,但是它忽略了一些关联性的问题。
从需求上来说,通过用例分析获得的用例一般都是相互独立的,但从系统的角度来说,有些问题是跨多个用例的。单个用例场景有时是无法描述一个问题的。领域模型就可以处理这种情况,提出一个问题,然后求解,在求解的过程中借用用例模型,将独立的用例场景通过问题串在一起将其“系统化”。
其次就是用例分析方法只能分析功能性需求,特别适合交互密集的需求。对于非功能性需求和计算密集型的需求则显得很为难。例如,用户有一个需求是用户界面可以个性化,这是一个非功能性需求,这时使用用例分析方法是很难分析的,但是如果把它转化成一个领域模型来看,得到结果可能是一个portal解决方案,这样问题领域就转化成技术选型的问题了。
- 领域模型的作用是什么?
在软件开发过程中,通常有一个疑惑,就是需求转到设计这层总是不好把握,总觉得没有根据,心里没底。在这方面除了分析模型可以处理,领域模型也可以帮助到。
领域模型对系统的架构和框架的建立可以起到指导作用。例如我们可以针对事务处理、日志处理、消息机制、编程模型建立领域模型,然后就可以吧业务对象和事务、日志这些属于架构和框架范围的东西结合起来。
有时候业务对象到设计类是有一定差距的,这就需要有一定的范式或指导来帮助进行这种转化。分析类是有效的过渡类型,但是由于分析类是由用例推导出来的,同样是不能描述非功能性需求,也不能表达跨用例的问题。但如果对这个问题建立领域模型,就可以得到业务对象是由哪些领域类组成,在项目的早期能知道业务对象的关系,对于设计类来说是很有帮助的,起码知道在设计类时哪些东西是必要的。
- 什么时候需要建立领域模型呢?
简单需求无需建立。
对核心业务建立。
针对难点建立。
关注非功能性需求。
- 建立领域模型的步骤是什么?
提出领域问题
就是对需要建模的核心业务或者其他提出问题,这些问题可能来自于企业的各个部门或者其他
分析领域问题
对每一个问题通过和它有关的业务用例场景图来分析,得到业务对象模型。
得到问题领域变量
建立领域模型
上述的问题领域变量就是领域模型的基本构成了。但是还不一定是最终的结果,在后续的开发过程中,随着业务的深入,可以增加、减少、合并这些变量。
验证领域模型
和业务用例模型一样,领域模型也分静态模型和动态模型。为了验证得到的领域模型是否是满足业务要求,可以把这些领域对象代入到各个业务用例模型中,看是否符合要求。
提取业务规则
- 业务规则主要分三类:全局规则,交互规则,内禀规则。
全局规则是适用于系统大部分业务或系统设计的,是跨用例的规则。全局规则是与用例无关的,是和系统具备的特性相关的。实际上,通常如授权、备份、事务等特性都是由系统框架去实现的,并不会分散到具体的功能中单独去实现它们。AOP模式就是试图将全局规则从业务逻辑当中剥离出来的一种编程模型。
交互规则是产生于用例场景中,通常这部分规则是最复杂,也最不稳定。大家所说的需求经常变更相信绝大部分就来自于此。如果需求无可避免地变更,那么将交互规则单独提取出来,通盘考虑并设计成为扩展性较强的结构就是一种有效的应对手段。在应付交互规则时,我们可以采用很多设计模式来保证扩展性。应用设计模式最重要的一点就是弄明白设计模式的意图和应用条件,交互规则恰恰提供了这些信息,我们就可以针对交互规则来决定是否应当采用某个设计模式。
内禀规则是指那些业务对象本身自有的。比如电话号码的位数、身份证的位数。通常写在业务对象描述文档中。如:
获取非功能性需求
- 如何获得非功能性需求呢?说简单也简单,说复杂也复杂。简单是因为非功能性需求总是比较固定的几个范围,完全可以通过固定的程序一个一个收集整理。说复杂是因为随着软件规模的不断扩大和应用环境的日趋复杂,要确定的非功能性需求指标需要考虑越来越多的因素。非功能性需求主要围绕下面几个方面展开:
- 可靠性:安全性、事务性和稳定性。
- 获取安全性需求时,应该充分考虑业务内容和应用环境。
- 事务性就是保障系统的ACID能力。
- 稳定性由故障的频率、严重性、可恢复性、可预见性、准确性和平均故障间隔时间(MTBF)等一些指标构成。
- 可用性:是用来衡量人们对软件产品的满意程度。
- 容易学习。
- 使用效率:客户需要多长时间、执行多少操作才能完成一个关键任务?
- 记忆性:当客户离开再次回来工作时,他的工作是否能记忆下来以便继续工作?
- 错误恢复:当系统出现故障时,客户是否能够从故障中恢复他已经完成的工作?
- 主观满意度。
- 人员因素:软件是否遵循了以用户为中心的设计方式。例如,界面布局是否符合客户的操作习惯;操作是否沿用了客户认同的术语;操作方式是否与客户的工作习惯相符等。
- 美观。
- 用户界面的一致性:软件是否能带给用户一致的操作体验。不一致的比如要跳到下一个界面,有的地方要点击菜单,有的地方要点击按钮,有的地方要点击超链接。
- 联机帮助和环境相关帮助。
- 向导和代理
- 用户手册和培训资料
- 有效性:性能、可伸缩性、可扩展性。
- 性能包括速度、并发性、吞吐量、响应时间、资源占用率等一些指标。
- 可伸缩性是指当向系统中增加资源时的性能改善,例如cpu、内存或计算机等。可伸缩性同时又分为垂直伸缩和水平伸缩两种情况。垂直伸缩性指为系统换置更高级、快速的设备时性能的改善程度。水平伸缩性是指当为现有的应用程序添加额外的、负载均衡的服务器时性能的改善程度。
- 可扩展性包含资源可扩展性、应用可扩展性和技术升级可扩展性。资源可扩展性指软件系统对增加改变。应用可扩展性是指,当硬件资源扩大时,应用是否能相应获得性能提升的能力。技术升级可扩展性是指,随着某项技术的升级,系统性能是否能够随之提升的能力。
- 可移植性。
- 在获取非功能性需求时,需要需求人员主动去引导,因为客户不是计算机专家,除了可用性之外,基本不考虑其他非功能性需求。即使提出,也是非常模糊。
需求分析
关键概念分析
- 需求分析的工作就是找到关键用例,然后对这些用例进行分析,并建立概念模型。
- 概念用例始于业务用例,而且是关键的业务用例。我们获取概念用例的目的是为了完成业务主线,因此,概念用例不必那么在意业务细节,而只需要非常概括地展现出能够完成业务主线的那一部分即可。
- 建立概念模型和建立业务模型差不多,都是通过一些时序图、活动图、协作图来分析用例,然后得到一些关键对象,这些对象都是一些实体对象,模型就是由这些关键对象构成的。
- 得到的这些实体对象显然不能使一个系统运行,可以采用分析模型的方式来实现核心业务。
业务架构
- 业务架构在软件开发中是很重要的,在某一行业做产品,做到最后就是沉淀出这个行业的业务架构,然后这些业务架构就可以不断地使用,或重新构建成该行业的其他的产品,或作为咨询。
- 但是业务架构的沉淀不是一朝一夕能达到的,首先有经验丰富的架构师,他在这个行业见过很多类似的项目,知道该沉淀什么东西,然后就是做产品的时候不断改进,持续总结。
- 它和软件架构是相辅相成的关系,但是软件架构要服务于业务架构,就像搭积木,业务架构师积木,软件架构是搭积木的方法,也就是策略,所以业务架构是很重要的,毕竟巧妇难为无米之炊。
- 业务架构由诸多构件组成,这些构件可以是一个业务功能单元,也可以是一个业务逻辑。
- 该怎么来构建业务架构呢?
- 采用自顶向下的方法,之前的业务用例模型、领域模型、概念模型在这里就派上了用场;业务用例模型提供了业务的细节,领域模型说明了要关注的问题,概念模型抓住了核心业务,有这些基础,一般来说,对这个项目有了一定的把握。
- 最好从概念模型入手,因为概念模型把握着整个核心业务,只要掌握了核心业务,就有自信说把握了整个项目。从核心业务流程找到粗粒度的构件,然后再细分这些构件,每个粗粒度的构件分出来的多个小构件应该可以用一个逻辑构件关联起来,形成一个整体。这些构件就是积木。
- 当这些构件做好后,不能认为这些构件做的就一定对,因为即使在这个企业可以用,在别的企业就有可能用不了了。所以一般要做很多个项目,不断调整,不断去积累才会在最后沉淀出一些可以拼图的构件。
- 在构建业务架构的时候,我们会发现这和功能分解有什么区别呢?再往上说,这和面向过程的结构化设计方法有什么区别呢?首先,面向过程是什么呢,在前面已经讲过,结构化设计方法得到是将过程分解成子系统或功能模块,比如一个项目按部门分、按业务分,都只是业务员处理过程中的一个小的过程。但是这样分的话有什么根据吗?仅仅是它是这个过程的一个小过程这样的理由就可以了吗?看来是不够充分的。而面向对象的方法中,业务架构建立的方法有着严密的推导过程,它从业务用例模型、领域模型、概念模型中推导。每个业务构件的产生都来自于各类模型和场景。虽然每个构件看起来是一个功能点,但是应该被看作是功能点的集合,是一个大的功能点。比如管理申请单构件,这个构件里面就包括申请单的生命周期管理,从产生到使用,围绕申请单这个实体类,提供一系列的服务和接口,就好像是一个巨大的类一般。这点在结构化设计中是做不到的。并且,结构化设计让我们感觉到“分解”的意思,而业务架构的方法则是“抽取”的感觉。
系统分析
确定系统用例
- 系统用例从业务用例细化而来,和业务用例的主要区别是描述的主体不一样,业务用例以业务为主,系统用例以系统为主,是站在计算机的角度来看,所以不是所有的业务用例都能转化成系统用例,因为有些事情计算机是做不到的,只能人工来做。
- 一般来说,首先分析业务用例场景,找到某某做什么,然后这些就是系统用例的来源,使用映射、抽象、合并、拆分、演绎这些方法来确定系统用例。
- 确定系统用例后,就要描述系统用例,描述系统用例的过程,也是系统建模的过程,和业务建模的过程差不多,采用的工具都是用例场景、用例规约、对象模型、用例实现、用例实现场景等。只不过我们的视角和建模目的已经从原来的描述业务、理解业务变成描述系统、理解系统。
分析业务规则
- 业务规则常常被看做是程序逻辑的一部分,导致业务规则要更改的时候,程序的控制逻辑也要作相应的修改。程序的控制逻辑是指要完成某个功能需要怎么去进行,而业务规则是指这个行业在进行某个业务时需要遵守的规则,按理说这两个应该要区分开来,业务规则是会经常变的。
- 对于整个系统都适用的这种全局规则应该交给架构师去处理,比如说这个系统运行的所有数据都要有备份,这时候如果让程序员来实现,是一件很痛苦的事情,每次操作数据库时都要考虑备份的事情,都要编写和这有关的代码,分散了对业务逻辑的注意,不太好,架构师来处理就不一样了,他们站在系统的顶层,使用一些设计或者是框架,就可以实现,让程序员不必关注这块。
- 对于交互规则,最好将他们独立成一个对象或者模块去使用,不应该把他们混入到业务逻辑代码中。
- 对于内禀规则,则让程序员去处理好了,将它们封装在对象中,也不要混入业务逻辑代码中。
用例实现
- 系统用例只是描述系统需求,是一种设想,用例实现是要把这种设想变成实现,我们采用的是面向对象的方法来分析,所以把设想变成实现就要用对象之间的交互来完成,那就要找到对象了。
- 首先就需要有系统用例、业务规则这些原材料,采用分析模型工具来得到分析类对象。
- 得到的分析类模型是需求通往实现的一道桥梁,它有很多优点。分析类高于设计实现,高于语言实现,高于实现方式。
软件架构和框架
- 架构描述的是软件应该做成什么样,是蓝图,而框架是半成品的项目。好比建房子,架构师说房子的墙壁应该刷成白色,那用什么样的油漆是框架说了算,架构只是描述要的样子就可以了。所以架构的东西一般会经常拿来给别人说,抽象的东西会比较容易懂,适合的人群种类也多,而框架是程序员接触的多,也只有他们才会懂,这是实现的细节。
- 大部分的软件架构都是由一个设计思想,加上若干设计模式,在规定一系列的接口规范、传输协议、实现标准等文档构成的。比如说j2ee规范描述了一系列逻辑部件,如session bean、entity bean、message driven bean、jaas、jdbc等,描述了这些部件的职责和它们的规范,约定了这些部件之间交互的接口和协议、标准,如soap、rmi、webservice等。并规划出一个如何利用这些部件实现一个应用系统的蓝图。
- 软件框架是可执行的,就是可以在计算机上运行。它通常是针对架构中某一特定问题提供解决方案和辅助工具。比如ibm的WebSphere是j2ee架构的一个实现,Struts、jsf、webwork是mvc架构的实现。
- 如果说业务架构是拼图单元的话,软件架构就是拼图的方法。拼图的方法不尽相同,但是无论如何,最后的结果都是将业务单元拼成了一幅完整的业务拼图。可以说业务架构+软件架构=业务系统。
- 当软件架构确定后,接下来要做的事就是把软件架构应用到业务系统中去。系统分析中,有提到使用分析模型来分析系统用例场景得到分析类,而系统用例是从概念模型中细化出来的,所以只要把分析类代入到软件架构中,就可以验证软件架构是否满足需求。
分析模型
- 软件架构包括软件层次、每一层次的职责、层次之间的接口、传输协议和标准以及每一层次上所采用的软件框架。
- 在把分析类代入到软件架构的过程中,首先做的是先分析好每一个分析类它应该处在软件架构的哪一个层次上,然后针对每一层次画出分析模型图,因为每一层次都有其对应的框架,所以可以从所使用的框架的架构设计思想以及这一层的业务得到分析模型图,进而得到分析类图。如果偷点懒,就可以将这些分析类一一对应转化为设计类,然后交互开发。
- 对于直接把需求转到设计类的朋友来说,分析模型可能是多余了,对于有经验的设计人员来说,分析模型不值一提,机械并且没有挑战。但是,越简单的事越容易做好,越不容易出错。而且分析模型利于经验的传播。
- 得到分析模型是粗放的,仅仅是对需求的一个最基本的实现。很多时候我们需要对这种实现进行优化,以满足一些灵活性、扩展性方面的要求。在优化的时候可以关注以下几点:容易变化的需求,这种就需要一定的扩展能力去应对,例如采用一些设计模式;结构化和耦合度调整,不好的结构是网状结构的,好的结构是树形结构,对象之间的依赖是单向的,不交叉的;交互集中点调整,若一个对象的交互非常多,他依赖或关联到很多类,这个对象就是问题多发地带了,优化的方法一般有重新规划职责、增加冗余对象、增加中间调和对象等方法。
组件模型
- 组件不是一种物理结构,不像包结构会将类组织在一起存放,组件是逻辑地引用、使用这些类,这些类组织在一起的目的不是为了存放,而是为了完成一组特定的功能。
- 什么时候考虑建立组件模型呢?
- 如果实施的项目是一个分布式系统,那么各节点上的部署的应用程序通常应当建立组件模型。
- 如果实施的项目需要向第三方提供支持服务。
- 如果实施的项目需要将某部分业务功能单独抽取出来形成一个可复用的单元,在许多系统或子系统中使用时
- 如果实施的项目需要与其他现存系统或第三方系统集成,集成的接口部分应当建立组件模型。
- 如果实施的项目采用了构件化的软件架构,例如soa,则应当建立组件模型。
- 组件只维护服务接口和调用实现类的方式。或者说组件只有服务信息与服务实现的绑定信息,而不包含实现细节。这种情况下,组件充当了服务调用者与服务实现之间的代理和中介的作用。
- 也正因为和实现的隔离,组件可以复用,可以独立变化,可独立部署。
部署模型
- 部署模型是软硬件相结合的产物。最直观的理解,就是哪些软件部分部署到哪些硬件设备上。
系统设计
接口设计
- 在设计接口时,可以基于相同行为设计,也可以基于相同服务设计。相同行为就是有相同方法的类,相同服务就是业务流程相似,但是业务内容不一样。
包设计
- 分包的目的除了将程序文件分类管理,最重要的就是要让软件组织有序并且职责清晰。一般来说,分包应当遵循自顶向下原则、职能集中原则和互不交叉原则。
- 通常情况下,应当遵循先应用自顶向下原则,再应用职能集中,再应用互不交叉原则的顺序。即先将类按软件层次分包,在每个软件层次中再按职能集中原则分包,最后再按互不交叉原则调整的顺序分包。
数据库设计
- 面向对象视图为动态的世界建模,它要描述的是世界运行的过程和规律,进而适应发展和变化,面向对象总是在变化中处理各种各样的变化。关系模型为静态的世界建模,它通过数据快照记录下了世界在某一时刻的状态,在任何你可以访问它的时候,它都是静止的。
- 面向对象致力于解决计算逻辑问题,关系模型致力于解决数据的高效存取问题。