Think in UML笔记第1章--为什么要UML
1.1 面向过程还是面向对象
面向过程和面向对象都是一种软件技术。例如把面向过程归纳为结构化程序设计、DFD图、ER模型、UC矩阵等,而面向对象则被归纳为继承、封装、多态、复用等具体的技术。事实上,上述的所有技术都只是人们在采用不同的方法来认识和描述这个世界时所采用的工具,它们都只是表征而不是本征。
UML创始人Grady Booch说过:我对面向对象编程的目标从来就不是复用。相反,对我来说,对象提供了一种处理复杂性问题的方式。这个问题可以追溯到亚里士多德:您把这个世界视为过程还是对象?在面向对象兴起运动之前,编程以过程为中心,例如结构化设计方法。然而,系统已经到达了超越其处理能力的复杂性极点。有了对象,我们能够通过提升抽象级别来构建更大的、更复杂的系统--我认为,这才是面向对象编程运动的真正胜利。
1.1.1面向过程方法
面向过程方法认为我们的世界时由一个个相互管理的小系统组成的。面向过程方法还认为每个小系统都有着明确的开始和明确的结束,开始和结束之间有着严谨的因果关系。
1.1.3面向对象方法
面向对象(Object Oriented,简称OO)方法将世界看作一个个相互独立地对象,相互之间并无因果关系,它们平时是“鸡犬之间相闻,老死不相往来”的。只有在某个外部力量的驱动下, 对象之间才会依据某种规律相互传递信息。这些交互构成了这个生动世界的一个“过程”。在没有外力的情况下,对象则保持着“静止”的状态。
从微观角度说,这些独立的对象有着一系列奇妙而古怪的特性。例如,对象有着坚硬的外壳,从外部看来,除了它用来与外界交互的消息通道之外,对象内部就是一个黑匣子,什么也看不到,这称为封装;再例如对象可以结合在一起形成新的对象,结合后的对象具有前两者特性的总和,这称为聚合;对象可以繁育,产下的孩子将拥有父辈全部的本领,这称为继承;每个对象都有多个外貌,在不同情况下可以展现不同的外貌,但本质只有一个,这就是接口;而多个对象却可能长着相同的脸,但同样的这张脸背后却是不同的对象,它们有着不同的行为,这就是多态。
从宏观角度说,对象是“短视”的,它不知道也无法理解它所处的宏观环境,也不知道它的行为会对整个宏观环境造成怎样的影响。它只知道与它有着联系的身边的一小群伙伴,这称为依赖,并与小伙伴间保持着信息交流的关系,这称为耦合。同时对象也是“自私”的,即便在伙伴之间,每个对象也仍然顽固地保护着自己的领地,这称为类属性,只允许其他人通过它打开的小小窗口,这称为方法,进行交流,从不允许对方进入它的领地。
然而对象也喜欢群居,并且总是“物以类聚,人以群分”。这些群居的对象有着一些像是的性质,它们依靠这些相似的性质来组成一个部落。对象们寻找相似性质并组成部落的过程称为抽象,它们组成的部落称为类;部落里的每个成员既有共同的性质又有自己的个性,我们只有把特有的个性付给部落成员才能区分它们并使它们活动起来,这称为实例化。
现实世界和对象世界之间存在着一道鸿沟,这道鸿沟的名字就叫做抽象。抽象是面向对象的精髓所在,同时也是面向对象的困难所在。实际上,要想跨越这道鸿沟,我们需要:
A、一种把现实世界映射到对象世界的方法。
B、一种从对象世界描述现实世界的方法。
C、一种验证对象世界行为是否正确反映了现实世界的方法。
闲话:今天你OO了吗?
如果你的分享习惯是在调研需求时最先弄清楚有多少业务流程,先画出业务流程图,然后顺藤摸瓜,找出业务流程中每一步骤的参与部门或岗位,弄清楚在这一步参与者所做的事情和天下表单的结果,并关心用户是如何把这份表单传给到下一个环节的。那么狠不幸,你还在做面向过程的事情。
如果你的分析习惯是在调研需求时最先弄清楚有多少部门,多少岗位,然后找到每一个岗位的业务代表,问他们类似的问题:你平时都做什么?这件事实谁交办的?做完了你需要通知或传达给谁吗?做这件事情你都需要填写些什么表格吗?。。。那么恭喜你,你已经OO啦!
1.2UML带来了什么
1.2.1什么是UML
UML的前身:由Booch创造的Booch方法,由Jacobson创造的OOSE、Martin/Odell方法,Rumbaugh创造的OMT、Shlaer/Mellor方法。这些方法虽然各部相同,但他们的共同的理念却是非常相似的。于是三位面向对象大师决定将他们各自的方法统一起来,在1995年10月推出了第一个版本,称为“统一方法”(Unified Method 0.8)。随后又以“统一建模语言”(Unified Modeling Language)UML 1.0的正式名称提交到OMG(对象管理组织),在1997年1月正式称为一种标准建模语言。之所以改名,是因为UML本身并没有包含软件方法,而仅是一种语言,我们将在1.3节统一过程简介中解释语言和方法的关系。
1.2.2统一语言
统一的目标就是形成标准。
1.2.3可视化
UML采用了“可视化”的图形方式来定义语言。UML通过它的元模型和表示法,把那些通过文字或其他表达方法很难表达清楚的,隐晦的潜台词用剪刀直观的图形表达和暴露出来,准确而直观地描述复杂的含义。把“隐晦"的变成”可视“的,也就是把文字变成图形,这才是UML可视化的真正含义。
例如下面的描述一辆汽车:
1.2.4从现实世界到业务模型
建立模型。UML提供了哪些元素来喂现实世界建立模型呢?
1.UML采用称之为参与者(actor)的元模型作为信息来源提供者,参与者代表了现实世界的”人"。参与者是模型信息来源的提供者,也是第一驱动者。换句话说,要建立的模型的意义完全被参与者决定,所建立得模型也是完全为参与者服务的,参与者是整个建模过程的中心。
2.UML采用称之为用例(Use case)的一种元模型来表示驱动者的业务目标,也就是参与者想要做什么并且获得什么。这个业务目标就是现实世界中的“事”。而这件事是怎么做的,依据什么规则,则通过称之为业务场景和用例场景的UML视图来描绘的,这些场景便是现实世界中的“规则”。最后,UML通过称之为业务对象模型的视图来说明在达成这些业务目标的过程中涉及到的事务,用逻辑概念来表示它们,并定义它们之间的关系。业务对象模型则代表了现实世界中的"物“。
UML通过上面的元模型和视图捕获现实世界的人、事、物和规则,于是现实信息转化成了业务模型,这也是面向对象方法的第一步。业务模型真实映射了参与者在现实世界的行为,得到业务模型仅仅是一个开始,要想将业务模型转化到计算机能理解的模型,还有一段路要走。这其中最重要的一步便是概念模型。
1.2.5从业务模型到概念模型
虽然上一节中现实世界被业务模型映射并且记录下来,但这只是原始需求信息,距离可执行的代码还很遥远,必须把这些内容再换成一种可以知道开发的表达方式。UML通过称之为概念化的过程(Conceptual)来建立适合计算机理解和实现的模型,这个模型称为分析模型(Analysis Model)。分析模型介于原始需求和计算机实现之间,是一种过渡模型。分析模型向上映射了原始需求,计算机的可执行代码可以通过分析模型追溯到原始需求;同时,分析模型向下为计算机实现规定了一种高层次的抽象,这种抽象是一种指导,也是一种约束,计算机实现过程非常容易遵循这种指导和约束来完成可执行代码的设计工作。
分析模型在整个分析设计过程中承担了很大的职责,起到了分成重要的作用。绘制分析模型最主要的元模型有:
- 边界类(Boundary)
。边界是面向对象分析的一个非常重要的观点。从狭义上说,边界就是大家熟悉的界面,所有对计算机的操作都要通过界面进行。
- 实体类(entity)
。原始需求中领域模型中的业务实体映射了现实世界中参与者完成业务目标时所涉及的事物,UML采用实体类来重新表达业务实体。
- 控制类(control)
。边界和实体都是静态的,本身并不会动作。UML采用控制类来表述原始需求中的动态信息,即业务或用例场景中的步骤和活动。
1.2.6从概念模型到设计模型
建立概念模型距离可执行代码已经非常接近了。概念模型使我们获得了软件的蓝图,接下来工作就是建造所需零部件了。
设计模型的工作就是建造零部件,组装过程。概念模型中的边界类可以被转化为操作界面或者系统接口;控制类可以被转化为计算程序或控制程序,例如工作流、算法体等;实体类可以转化为数据库表、XML文档或者其他带有持久化特征的类。这个转化过程也是有章可循的,一般来说,可以遵循的规则有:
- 软件架构和框架。软件结构和框架规定了实现类必须实现的接口、必须继承的超类、必须遵守的编程规则等。例如采用J2EE架构时,Home和Remote接口就是必需的。
- 编程语言。各类编程语言有不同的特点,例如在实现一个界面或者一个可持久化类时,采用C++还是java作为开发语言会有不同的设计要求。
- 规范或中间件。如果决定采用某个规范或采用某个中间件时,实现类还要遵循规范或中间件规定的那些必需特性。
1.2.7mianx 对象的困难解决了吗
要解决面向对象的困难我们需要这样一些方法:
- 一种把现实世界映射到对象世界的方法。
- 一种用对象世界描述现实世界的方法。
- 一种验证对象世界行为正确反映了现实世界的方法。
1.2.7.1从现实世界到业务模型
这是把现实世界映射到对象世界的第一步。UML采用用例这一关键元素捕获了现实世界的人要做的事,再通过用例场景、领域模型等视图将现实世界的人、事、物、规则这些构成现实世界的元素用UML这种语言描述出来。而UML本身被设计成为一种不但适于现实世界理解,也适于对象世界理解的语言,所有用UML来描述现实世界这句话可以稍微换一个说法,变成:现实世界被我们用一种对象型语言描述。
1.2.7.2从业务模型到概念模型
这是从对象世界来描述现实世界的方法。当业务模型用分析类来描述的时候,我们实际上已经采用了对象视角。用例所代表的现实的业务流程,被“边界”、“控制”、“实体”以及“包”、“组件”等概念替代。而这些概念是可以被计算机理解的,是抽象化了的对象。
1.2.7.3从概念模型到设计模型
这是严重对象世界是否正确反映了现实世界的方法。“边界”、“控制”、“实体”这些对象化的概念,虽然是计算机可以理解的,但它并不是真正的对象实例,即他们并不是可执行代码,概念模型只是纸上谈兵。真正的对象世界行为是由Java类、C++类、EJB、COM+等这些可执行代码构成的。如图1.8展示信息指出,设计类并不是像孙悟空一样从石头缝里蹦出来的,而是用某种语言在某种特定规范的约束下”实例“话分析类的结果。换句话说,设计模型是概念模型在特定环境和条件下的”实例“化,实例化后的对象行为”执行“了概念模型描述的那些信息,因此设计模型得以通过概念模型追溯到原始需求来严重对象世界是否正确反映了现实世界。
把这三个模型的建立过程综合起来,形成图1.9所示,可以更清楚地看到面向对象的困难时如何在模型的转换过程中解决的。这一过程看来是由规律、可推导、可追溯的过程。
在图1.9中引入了另外一个概念,就是用例驱动。尽管在这一章并没有讲述这个概念,但是相信读者也能从中初步地领略到用例是如何驱动这个开发过程的。请读者机制这幅图,本身后续大量的篇幅都是由用例驱动来完成整个软件过程的。
1.3统一过程简介
谈到UML不能不谈到统一过程,即RUP。UML和RUP师出同门,尽管目前仍有许多其他的建模方法,不过RUP仍然是其中对UML使用最为全面的,同时也是最为复杂的。
1.3.1RUP是什么
严格来说UML并不是一个方法,而只是一种语言。UML定义了基本元素,定义了语法,但是如果要做一个软件项目,还需要有方法的指导。UML在完成一个软件项目,也需要有方法来指导,RUP无疑是目前与UML集成和应用最好、最完整的软件方法。
RUP(rational Unified Process)译为统一过程。统一过程并非是因为UML才诞生的,也不是最近才出来的软件方法,而是有着很长时间的发展,有着很深的根源。统一过程归纳和整理了很多在实践中总结出来的软件工程的最佳实践,是一个采用了面向对象的思想,使用UML作为软件分析设计语言,并且结合了项目管理、质量保证登许多软件工程知识综合而成的一个非常完整和庞大的软件方法。
统一过程归纳和集成了软件开发或者中的最佳实践,它定义了软件开发过程中最重要的阶段和工作(四个阶段和九个核心工作流),定义了参与软件开发过程的各种角色和他们的职责,还定义了软件生产过程中产生的工件,并提供了模板。最后,采用演进式软件生命周期(迭代)将工作、角色和工件串在一起,形成了统一过程。
工件:工件也称为成果物或者制品(artifact),这与可交付物(deliverable)是有些差别的。当某个或某些工作是最终产品的一部分需要交付出去时,才被称为可交付物。而在软件生产过程中任何留下记录的事物,都可称为工件。
从图1.11中读者可以看到,统一过程将软件生产分为了四个阶段和九个核心工作流。
1.3.3RUP与软件工程
为什么药投入那么多成么来实施统一过程呢?
- 一方面是出于提高软件成熟度的需要。我们知道CMM只规定了每个成熟度登记的苹果标准,但没有规定如何做才能达到这一标准。与其耗费更大的成本区摸索自己的软件过程,不如采用统一过程这种已经集成了软件活动的最佳实践的成熟的软件过程。实际上能够实施统一过程大致已经相对于到了CMM二级到三级的水平。
- 另一方面是出于提高软件技术水平和质量的需要。我们知道要生产一个好的软件产品,必须保证需求、分析、设计、质量等工作。统一过程由于集成了面向对象的方法、UML语言、核心工作流、工件模板和过程知道等许多知识,使得软件生产工作能够利用这些成熟的指导来提高组织内整体软件认识水平和开发人员的软件素质,借此提高软件产品的技术水平和质量。
- 再一方面,统一过程适于开发稳定的架构,它通过不断的演进逐步推进软件产品,这一特点使得它特别适合长期战略的软件产品。
但是统一过程由于太过庞大何复杂,相对于轻量级的敏捷方法,如XP(极限编程)方法来说,显得死板和难以实施。对于较小的组织和项目来说,使用统一过程的确有些费力不讨好,也因此找来了许多质疑。
另外,RUP和XP也不是非此即彼的关系,比如在造F-35的过程中,对整体飞机来说,用RUP是适合的,具体到零部件到时大可XP一把,现在风洞里试验试验,不符合条件就更换了再试,最终只要得到最适合的零部件就OK了。
1.3.4RUP与最佳实践
统一过程集成了很多过程类的最佳实践,这些最佳实践中包括用量驱动、架构导向、构件化等。通过学习统一过程来全面认识软件是怎么一回事是一个提升自我能力的捷径,无论读者是程序员、设计师、系统分析员、架构师、测试人员、项目经理、需求工程师、配置管理员等等,都将在统一过程中找到自己在一个软件生产过程中的位置,找到自己的职责,以及与其他角色的互动,进而从更高的层次和整体上提升自身的软件能力。