<二>面向对象分析之几个关键的概念
一:建模
--->建模,是指通过对【客观事物】建立一种抽象的方法用以表征事物并获得对事物本身的理解。同时把这种理解概念化,将这些逻辑概念组织起来,构成一种对所观察对象的内部结构和工作原理的便于理解的表达。
--->建模怎么建?首先要决定的是抽象角度,即建立这个模型的目的是什么?一旦抽象角度确定,剩下的事情就变得顺理成章,而不是杂乱无章。
例如“请在30秒说出尽可能多的勺子,筷子,盘子的相同点和不同点?
(1)对一组事物,从一个角度切入,找出他们的相同点,不同点。静态属性,动态行为。
(2)做需求的时候,首要目标不是要弄清楚业务是如何一步一步完成的。而是要弄清楚有多少业务的【参与者】?每个业务的参与者的目标是什么?【参与者的目标】就是你的抽象角度。与分析一个复杂的业务流程相比,单独分析参与者的一个个目的要简单得多。实际,这就是【用例】。这也就是为什么【用例】会成为业务建模的方法的原因之一。
---->建模的模是什么?一但决定了抽象角度,就确定了一个目标。现在,要做的事情便是找出那些能够满足这一目标的事物。这并不容易。有趣的是,我们找出这些事物的过程其实并不是面向对象的,而是过程化的,这是因为要达到一个目标必须要有动作附加在静态事物上,并产生一定的效果。这样一来,我们必须要搞清楚谁发出了什么动作,作用于什么事物,产生了怎样的后果。显然这中描述方式是过程化的。但是与面向过程方法不同的是。我们描述这个过程化的场景并不是最终目的。而是为了找出场景当中贡献于场景目标的那些事物,以及这些事物是如何贡献于这个场景的。也就是说场景模拟帮助我们找出抽象的对象。而场景本身则是这些对象在一定条件下交互的一个特定结果。当条件变化的时候,场景就会随之改变,我们并不试图控制这个场景。
(1)现在回到什么是模的问题上来,一个由抽象角度确定了的目标需要由静态的事物加上特定条件下产生的一个特定场景来完成。即【静态的事物(物)】+
【特定的条件(规则)】+【特定的动作(参与者的驱动)】=特定的场景(事件)
(2)模就是“人”,“事”,“物”,“规则”。
---->建模公式
二:用例驱动
---->用例驱动是统一过程的重要概念,或者说整个软件生产过程就是用例驱动的。
---->在实际的软件项目中,一个软件要实现的功能通过用例来捕获,接下来的所有分析,设计,实现,测试都是由用例来驱动的。在统一过程(RUP)中,一个用例就是分析单元,设计单元,开发单元,测试单元,甚至部署单元。
---->在统一过程中,用例捕获了系统的功能性需求。参照建模公式,我们确定它代表了软件系统要解决的问题领域。
---->逻辑视图:系统只有一个逻辑视图,该视图以图形方式来说明关键的用例实现,子系统,包和类,它们包含在架构方面具有重要意义的行为。即建模公式中的那些“人”,“事”,“物”,“规则”是如何分类组织的。
---->进程视图:为了便于理解系统的进程组织,在“分析设计”工作流程中使用了名为进程视图的架构视图。系统只有一个进程视图,它以图形方式说明了系统中进程的详细组织结构,其中包括类和子系统到进程和线程的映射,即建模公式中那些“人”,“事”,“物”,“规则”是如何交互的,他们的关系如何。这个视图是我们常说的分析设计视图。
--->部署视图:系统只有一个部署视图,它以图形方式说明了处理活动在系统中各节点的分布,包括进程和线程的物理分布,即建模公式中那些“人”,“事”,“物”,“规则”是如何部署在物理节点(主机,网络环境)上的。
--->实施视图:实施视图的作用是获取为实施定制的架构决策,实施视图通常包含以下内容
(1)列举实施模型中所有子系统
(2)描述子系统如何组织为层次和分层结构的构件图。
(3)描述子系统间的导入依赖关系的图解。
实施视图用于:
(1)为个人,团队或分包商分配实施工作
(2)估算要开发,修改或删除的代码数量
(3)阐述大规模复用的理由
(4)考虑发布策略
也就是建模公式中的那些“人”,“事”,“物”,“规则”如何构成系统的“零部件”,以及我们如何组织人力生产和组装这些“零部件”以建成最终系统。
三:抽象层次
---->抽象层次是面向对象方法中极其重要,但是又非常难以掌握的技巧。学会站在不同的抽象层次考虑问题是建立好模型的基础。
---->抽象层次越高,具体信息越少,但是概括能力越强。反之,具体信息越丰富,结果越确定,但相应的概括能力越弱。
---->抽象有两种方法:一种是自顶向下,另一种是自底向上。
(1)自顶向下的方法适用于让人们从头开始认识一个事物。例如介绍汽车的工作原理,从发动机,传动装置,变速器等较高层次的抽象概念来将就比较容易明白。如果降低一个层次,从发动机原理讲起,一大部分听众就会开始迷惑。再降低一个层次,从热力学原理和力学原理讲起,那就更没人能搞懂汽车是怎么工作的。
(2)自底向上的方法适用于在实践中改进和提高认知。例如在实践中发现发动机的问题,因而改进发动机结构,甚至采用新的发动机原理,最终能提升汽车的质量。
四:视图
----->视图是UML建模中另一个非常重要的概念。视图用于组织UML元素,表达出模型某一方面的含义。视图的准确应用是建立好模型的一个重要组成部分。视图的应用看上去似乎并不太复杂,但在实际工作中很多人并不知道应该在什么地方应用视图,应用哪一种视图,总共需要那些视图。例如,绘制流程图时,到底是用活动图还是交互图呢?
----->UML里定义了用例图,对象图,类图,包图,活动图,流程图等不同的视图。
----->视图和视角是两个相互辅佐的概念。一个给特定人员看的视图,一定要选好视角。
比如:一个喜欢车型的人,就给他从车型角度描述的视图。
客户,开发人员,测试。他们对一个软件的视图是不同的。客户要的是产品架构图,开发人员要的是某个模块的用例视图。测试人员,要的是功能的规则图。
----->视图和视角是两个被忽略的关键概念,对建立一个好的模型起很重要的作用。为特定的信息选择正确的视图,为特定的干系人展示正确的视角并不容易。需要因时因地因人制宜。
问题一:应该为那些软件信息绘制那些视图?
问题二:应该给那些干系人展示那些视角?
四:对象分析方法
----->一切都是对象:在面向对象的眼睛里,一切有名字的东西都是对象,都应该使用对象的观点来看待它,分析它。哪怕这个东西的名字叫某某业务流程,它也仍然应看作是一个对象。而不是一个过程。这意味着,无论什么时候都应当采用接下来的观点和方法看待和分析事物。
---->对象都是独立的:独立性是面向对象的一大特点。对象和对象之间是天然独立的。只是在某个特定的场景下,他们的某一个特定的实例才项目联系在一起。
---->我们获取和分析对象的手段经常是通过分析某个场景。但需要知道,对象是离散的。
(1)它不是因为该场景而存在的。场景中的对象只是对象“映射”到该场景的一个侧面。因为这个对象将来会参与很多现在未知的场景。换言之,通过一个场景,我们仅能得到对象的一个侧面信息。
(2)从每个场景看到的仅是对象映射到该场景的一个方面,或者说是一个实例。它仅仅是对象分析的开始。请记住,当采用面向对象的方法时,在需求,分析,设计过程中。你所得到的任何一个有名字的东西,不论是用例,类,包,组件等都是独立于那个场景。我们应该从多个场景中该对象的实例中归纳出一般特性,也就是公共部分。用于抽象。对象的独立性带来的正是对象的可抽象能力和可扩展能力。
---->对象都是具有原子性的。
(1)在分析过程中都应当将对象看作一个不可分割的原子,哪怕这个对象规模很大,只要我们认为它是个对象,它与其他对象交互时就是一个整体。
(2)在分析过程中,对象总有一个边界。永远不应该打破边界去窥探对象内部。形象说:对象看上去就像一个个鸡蛋。蛋壳就是对象的边界。在分析对象过程中,我们对它的所有理解都来自蛋壳。如果因为我们好奇心太重视图了解蛋壳以内的世界,冲动地打破了边界,恩,的确看到了,好奇心满足了,不过后悔,因为蛋碎了。
(3)我们应当将分析过程中得到的所有对于对象的认识附加在对象边界上,在实现这个对象之前不理会其内部的细节。这称之为面向接口编程。
----->对象都是可抽象的。
(1)对象有着很多个不同的方面,一般来说,对象参与一个场景时会展现出某一个方面。总可以将对象的某一个方面抽象出来,让其作为对象的一个代表来参与场景交互。通常这种抽象会以接口来命名。在分析过程中,得到的任何一个对象都有特定的方面可作为抽象。因为对象总是从场景分析中得到的,它在场景中肯定展现了一个方面。对象所具有的方面,或者说对象所参与的场景越多,对象越有抽象的价值。反之则越没有抽象的价值。因此在分析过程中,应当关注那些参与了很多场景的对象,他们往往是分析设计的重点以及成败关键。
----->对象都有层次性。
(1)对象是有着抽象层次的。层次越高,其描述越粗略但适应能力越广。层次越低则描述越精确但适应能力越下降。
(2)不论是在需求,分析还是设计过程中,都应当具备抽象层次的观点。从需求到设计的过程已经是几个不同的抽象层次。笔者要说的是,在其中的一个阶段,例如需求阶段,仍然可以再多分几个抽象层次来说明。今天分多少抽象层次应该看问题领域的复杂度而定。
------>对象分析方法总结
(1)独立性,原子性,抽象性,层次性是面向对象分析时应当遵循的一些原则和方法。