第14章 使用UML

  在探索UML的细节之前,我们应该先讲讲何时以及为何使用它。UML的误用和滥用已经对软件项目造成了太多的危害。

14.1 为什么建模

  建模就是为了弄清楚某些东西是否可行。当模型比要构建的真实实体便宜很多时,我们就会使用模型来研究设计。

14.1.1 为什么构建软件模型

  当我们有一些确定的东西需要测试,并且使用UML要比使用代码测试的代价更低一些是,就使用UML。比如,我有一个关于某个设计的想法。我想知道团队中的其他开发人员是否认为它是一个好的想法,于是,我就在白板上画一幅UML图,并询问团队成员的意见。

14.1.2 编码前应该构建面面俱到的设计吗

  其实,我们根本无法清楚地知道在编写代码前先创建面面俱到的UML设计到底是不是一件划算的选择。

14.2 有效使用UML

  我们不能像其他工程学科使用蓝图和模型那样轻率地使用UML。那么,我们应该什么情况下使用UML呢?

  在和他人交流及帮助解决设计问题方面,图示是最为有用的。重要的一点是,图示的详细程度应该只是达成目标所必须的。你可以绘制具有大量装饰的图示,但那是损害生产力的做法。请确保图示简单、干净。UML图不是源代码,不应该当做声明所有方法、变量和关系的地方。

14.2.1 与他人交流

  使用UML在软件开发者间交流设计构想是非常方便的。在交流算法细节方面,UML并不是非常适合。

14.2.2 脉络图

  在创建大型系统的结构脉络图(road map)方面,UML也很有用。这种脉络图可以使开发者快速找到类之间的依赖关系,并提供了一份关于整个系统的参考。

14.2.3 项目结束文档

  编写需要保存的设计文档的最好时机是在项目结束时,并把它作为团队的最后一项工作。这种文档会精确地反映出设计的状态,对后续的团队来说非常有用。UML图必须经过仔细考虑,我们不需要数千页的顺序图。我们想要的是那些描述系统关键点的少量重要的图示。

14.2.4 要保留的和要丢弃的

  请养成丢弃UML图的习惯。大部分UML图都不应该长久存在。仅仅需要保留那些具有高的长期存在价值的图示。
  有些图保持起来是有用的:那些表达了系统中公共设计方案的图示。请把那些记录了难以从代码中识别出来的复杂协议的图示保存起来。这些图示提供了系统中不常提及部分的脉络图。它们以一种比代码更好的表达方式记录了设计者的意图。

14.3 迭代式改进

14.3.1 行为优先
  我喜欢从行为开始。如果我认为UML会有助于我思考一个问题,我会首先绘制一幅有关问题的简单顺序图或者协作图。以手机完成电话呼叫为例。

  我们可以想象软件检测每一次按键,并向控制拨号的某个对象发送消息。因此我们绘制出一个Button对象和一个Dialer对象,以及Button向Dialer发送的多条digit消息。

  当Dialer收到一条消息时把这个数字显示在屏幕上。

  Dialer最好能让扬声器发出声音。因此我们让它向Speaker对象发送tone消息。

  在某个时候,用户会按下Send按钮,表示号码已拨完。此时,我们得让手机无线通信装置区连接手机网络并把所拨的电话号码传递出去。

  一旦连接建立起来,Rado就可以让Screen点亮“正在使用”指示灯。这条消息无疑得从一个不同的控制线程中发出,这一点是通过消息序号前面的字母来表示的。最终的协作图如下:

14.3.2 检查结构

  为了研究这幅协作图对于代码结构来说意味着什么,因此我们创建了一幅类图:

  为了隔离Button和Dialer:

Dialer不需要一个名为buttonPressed的方法,为了隔离Dialer和ButtonListener,使用了适配器:

14.3.3 想象代码

  如果画图不能想象出它所表示的代码,那么就是在构建空中楼阁。停止绘图,想一想该如何把它翻译成代码。决不为了画图而画图。

14.3.4 图的演化
  我们很可能是在一块白板前做这些,并且可能不会记录下所做的工作。我们不想非常规范或者非常精确。使用白板的目的不是为了让消息序号中的每一个点都正确,而是为了让站在白板前的每个人都能理解讨论的内容,是为了赶快停止讨论,开始编码。

14.4 何时以及如何绘制图示

  不要指定“必须图示一切”这样的规则。大量的时间和精力会浪费在绘制没人会看的图示上面。

  可以绘图的情况如下:

  • 几个人都需要理解设计的某个特定部分的结构,因为他们都将同时工作于其上。当每个人都认为已经理解时,就停止。
  • 你希望团队能够达成一致,但是有两个或者更多人不同意某个特定元素的设计。把讨论限定在一个时间盒内,然后选择一种策略的手段,比如:投票或者公平裁判。在时间盒终止或者能够做出决策时就结束。然后擦掉图示。
  • 你想尝试一个设计想法,并且图示能够有助于你进行思考。当你可以使用代码完成思考时就停止。丢弃掉图示。
  • 你想向其他人或者自己解释代码某些部分的结构。当通过浏览代码可以更好地进行解释是就停止。
  • 快要到达项目的尾声,并且客户要求把图示作为向他人提供的一组文档中的一部分。

  不要画图的情况如下:

  • 过程要求。
  • 不画图会有负罪感或着认为这是好的设计者要做的事情。编写代码才是好的设计者要做的事情。他们仅在必要时才画图。
  • 为了在编码前创建出面面俱到的设计阶段文档。这种文档基本上没有任何价值,却浪费了大量时间。
  • 为了让其他人编码。真正的软件架构师要参与到自己设计的编码中。

14.5 结论

  UML是一个工具,不是最终结果。作为一个工具,它可以帮助你思考和交流设计。如果少量使用,它会给你带来巨大好处。如果过度地使用,它会浪费你大量时间。当使用UML时,少即是好。

摘自:《敏捷软件开发:原则、模式与实践(C#版)》Robert C.Martin    Micah Martin 著

转载请注明出处:

作者:JesseLZJ
出处:http://jesselzj.cnblogs.com

敏捷软件开发:原则、模式与实践——第14章 使用UML的更多相关文章

  1. 敏捷软件开发 原则 模式 与实践 - OCP原则

    最近在读BOB大叔的敏捷软件开发,特别是TDD那一章节,启示真的不少,从测试驱动开发,讲到驱动表明程序设计的意图,从设计意图讲到对象依赖的解耦,从解耦建立Mock对象. 其实是对每个模块都编写单元测试 ...

  2. 《敏捷软件开发-原则、方法与实践》-Robert C. Martin读书笔记(转)

    Review of Agile Software Development: Principles, Patterns, and Practices 本书主要包含4部分内容,这些内容对于今天的软件工程师 ...

  3. 敏捷软件开发vs传统软件开发

    摘要 本文介绍了传统软件开发(着重介绍了传统软件开发中常用的瀑布模型)和敏捷软件开发,以及敏捷开发和传统开发的对比. 一.传统软件开发 比较常用的几种传统软件开发方法:瀑布式开发.迭代式开发.螺旋开发 ...

  4. 敏捷软件开发_实例2<四>

    敏捷软件开发_实例2 上一章中对薪水支付案例的用例和类做了详细的阐述,在本篇会介绍薪水支付案例包的划分和数据库,UI的设计. 包的划分 一个错误包的划分 为什么这个包是错误的: 如果对classifi ...

  5. 敏捷软件开发:原则、模式与实践——第12章 ISP:接口隔离原则

    第12章 ISP:接口隔离原则 不应该强迫客户程序依赖并未使用的方法. 这个原则用来处理“胖”接口所存在的缺点.如果类的接口不是内敛的,就表示该类具有“胖”接口.换句话说,类的“胖”接口可以分解成多组 ...

  6. 敏捷软件开发:原则、模式与实践——第10章 LSP:Liskov替换原则

    第10章 LSP:Liskov替换原则    Liskov替换原则:子类型(subtype)必须能够替换掉它们的基类型(base type). 10.1 违反LSP的情形 10.1.1 简单例子 对L ...

  7. 敏捷软件开发:原则、模式与实践——第8章 SRP:单一职责原则

    第8章 SRP:单一职责原则 一个类应该只有一个发生变化的原因. 8.1 定义职责 在SRP中我们把职责定义为变化的原因.如果你想到多于一个的动机去改变一个类,那么这个类就具有多于一个的职责.同时,我 ...

  8. 【Scrum】-NO.40.EBook.1.Scrum.1.001-【敏捷软件开发:原则、模式与实践】- Scrum

    1.0.0 Summary Tittle:[Scrum]-NO.40.EBook.1.Scrum.1.001-[敏捷软件开发:原则.模式与实践]- Scrum Style:DesignPattern ...

  9. 敏捷软件开发:原则、模式与实践——第13章 写给C#程序员的UML概述

    第13章 写给C#程序员的UML概述 UML包含3类主要的图示.静态图(static diagram)描述了类.对象.数据结构以及它们之间的关系,藉此表现出了软件元素间那些不变的逻辑结构.动态图(dy ...

随机推荐

  1. Click Models for Web Search(1) - Basic Click Models

    这篇文章主要是介绍一些基本的click model,这些不同的click model对用户与搜索结果页的交互行为进行不同的假设. 为了定义一个model,我们需要描述出observed variabl ...

  2. Linux - 进程状态

    ps report a snapshot of the current processes. 能提供一份当前进程的快照,以列表的形式显示正在运行的进程. 列出进程的数量取决于命令所附加的参数,例如:p ...

  3. 转载:第六弹!全球首个微信小程序(应用号)开发教程!通宵吐血赶稿!

    大家好!博卡君原计划是能在国庆假期前把小程序的开发教程做完,给大家一套完整.系统的东西,不过由于最近小程序开发工具的拍照组件尚未完善,很多功能还不能顺利实现.我考虑了一下,觉得不如把拍照部分的一些代码 ...

  4. Use the PDFs below or the HTML contents to the left to install and configure P6 EPPM and its additional components.

    Welcome to Your Documentation   Use the PDFs below or the HTML contents to the left to install and c ...

  5. Linq之select子句

    在Linq中select子句用来指定查询结果的类型和表现形式.Linq查询要么以select子句结尾,要么以group子句结尾. List<UserBaseInfo> users = ne ...

  6. 【C#】属性(Attribute)

    如果程序员是猫,你是哪只猫? 这个是我一直都很喜欢的一个技术,不是很麻烦,也不是很难理解,和反射配合起来,只有你想不到没有做不到的用途(夸张了哈). 运用范围 程序集,模块,类型(类,结构,枚举,接口 ...

  7. C语言中有bool类型吗?

    之前一直都没有注意到,最近在用C语言写DSP算法时,偶然间发现我函数中定义的bool类型的变量在VC6.0(我主要用它来检查一下语法错误)中编译居然报错了,说是bool类型没有定义.用了这么久的C和C ...

  8. 【jQuery基础学习】08 编写自定义jQuery插件

    目的:虽然jQuery各种各样的功能已经很完善了,但是我们还是要学会自己去编写插件.这样我们可以去封装一些项目中经常用到的专属的代码,以便后期维护和提高开发效率. jQuery插件的类型: 封装对象方 ...

  9. 用于dbnull的数据转换。因为用convert.to无法转换dbnull类型

    /// <summary> /// add by wolf /// </summary> public static class ExtendObject { public s ...

  10. 获取datatable更新之前的数据

    string dd = ds.Tables[0].Rows[0][0, DataRowVersion.Original].ToString() ;