第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. IE11之F12 Developer Tools--概述篇

    打开Developer Tools的方法: a. 点击F12 b. 在浏览器中选择Tools-->F12 Develooper Tools 打开后图示: 从上图我们可以看到,Developer ...

  2. 专题——web.xml 中 url-pattern

    一.映射什么? 一个请求发送到 servlet 容器,servlet 容器会将当前请求的 url 路径减去 协议.端口号.contextPath,剩下 servletPath 就是用来做 url-pa ...

  3. Web前端面试题集锦

    前端开发面试知识点大纲: 注意 转载须保留原文链接(http://www.cnblogs.com/wzhiq896/p/5927180.html )作者:wangwen896 HTML&CSS ...

  4. 用Qt写软件系列二:QCookieViewer(浏览器Cookie查看器)

    预备 继上篇<浏览器缓存查看器QCacheViewer>之后,本篇开始QCookieViewer的编写.Cookie技术作为网站收集用户隐私信息.分析用户偏好的一种手段,广泛应用于各大网站 ...

  5. 有关CLR的初学小整理(可能理解不深刻,望大牛指出)

    1. .Net程序通过CLR去加载运行管理代码, 加载CLR的进程成为“宿主”,通常操作系统加载. 加载CLR的进程也可以为某个DLL,也成为“宿主” 2. 宿主接口使宿主能够对运行库的更多方面进行控 ...

  6. MySQL服务器权限表

    MySQL服务器通过权限表来控制用户对数据库的访问,权限表存放在mysql数据库里,由mysql_install_db脚本初始化.这些权限表分别user,db,table_priv,columns_p ...

  7. csharp: 用Enterprise Library对象实体绑定数据

    Enterprise Library: https://msdn.microsoft.com/en-us/library/ff648951.aspx /// <summary> /// 是 ...

  8. spring报nested exception is java.lang.IllegalArgumentException: @EnableAsync annotation metadata was not injected错误

    http://www.oschina.net/question/1539472_159699

  9. phpcms--使用添加php原生支持

    1,phpcms模板中有时候要添加一些php相关变量这个时候要使用原始php的东西,可以如下加入 {php $no_wq_id=$r[id] ;}其中$r[id]是通过{pc:get sql=&quo ...

  10. mysql oom之后的page 447 log sequence number 292344272 is in the future

    mysql oom之后,重启时发生130517 16:00:10 InnoDB: Error: page 447 log sequence number 292344272InnoDB: is in ...