<<UML for Java Programmers>> 第11章读书笔记

这一章提到新手做设计时的常见错误。

我最喜欢这一章,以前看的时候,为了追求所谓的速度,把书中的实例统统略过,真有点买椟还珠的味道。另外说明一下,读书笔记为什么突然跳到第11章。

最简单的原因是因为我对这一章有感觉,觉得有必要做笔记。

常见的如下:

1. 没有方法的类(MissingMethods)。没有方法的类是没有存在价值的,“programs are about behavior!”,我们应该根据行为来划分软件系统。如果不是根据行为来划分软件,说明用了其它错误的划分方法。

2. 真空类(Vapor Classes)。书中有个Light的类,这个类没有数据成员,只有两个方法:on和off,这两个方法也是做了一个简单的转换,方法里只有一句,调用了CoffeeMakerAPI的函数,没有做任何有意义的事,去掉它完全不影响软件逻辑。除了Light外,Button、Boiler和WarmerPlate也是这样的类,去掉对逻辑没有任何影响。

3. 假想的抽象(Imaginary Abstraction)。因为咖啡机的需求描述里提到了几种加热器和传感器,初学者会想当然的弄出一个传感器的抽象基类。如何判断基类是否合理呢?看有没有其它类会用到它。另外,如果抽象类的接口太泛化,也是错误抽象的一个提示。假想的基类之所以出现,是因为大家按照需求规格书,从里面挑名词,然后根据这些名词提取抽象。

4. 神一样的类(God Classes)。如果所有责任都在一个类的身上,也许你创建了一个全能类。全能类是我们要避免的,这就是我们做设计的原因。

提了这么多错误和注意事项,那么,正确的咖啡机程序该如何设计呢?

"The trick to solving this problem is to step back from the problem and separate the

details from the essential nature of the problem. Forget about boilers, valves, heaters, sensors,

and all the little details of the problem and concentrate on the underlying problem.

What is that problem? The problem is: How do you make coffee?

How do you make cofee? The simplest, and most common solution to this problem, is

to pour hot water over coffee grounds, and to collect the resulting infusion in some kind of

vessel. Where do we get the hot water from? Let’s call it a HotWaterSource. Where do

we collect the coffee? Lets call it a ContainmentVessel."

如书中所说,要忽略细节,看清问题的本质。

煮咖啡就是将热水倒在咖啡渣上,然后用个容器接收滤出的水。所以咖啡机由两个东西构成:HotWaterSource和ContainmentVessel。这两个类之间有什么样的依赖关系呢?初学者容易将方位的上下映射到类的依赖中,这是不对的。类的依赖关系应该反映message的流动,其实就是谁给谁发消息。书中将这种连线错误称之为Crossed Wires。

有了这两个类就够了吗?不够。还要添加用户界面,不然用户无法使用咖啡机。为此,作者添加了UserInterface类,负责和用户交互的一切。

这个三元组如何配合呢?怎么样来确定每个类的行为?答案是从行为触发,通过用例来看这三个类之间有哪些消息需要传递。可以用协作图将关系表达出来。完成了动态图之后,可以将静态的类图也画出来。

静态图和动态图都有了,这样就完了吗?我觉得这样就差不多了。但是作者却说“No, No, No”(OK,这一句是我想象的)。

理想中的咖啡壶已经设计好了,马上把它在代码里实现吧!

作者提到,如果将M4咖啡壶的细节掺入刚刚设计好的类中,那么刚才的抽象工作白做了。为了设计可以复用,必须将不能重用的部分分开。所以才有了后面“Use Case 1. User pushes Brew Button (Mark IV)” 等几节。一般书上都是从生活到艺术,这一章作者从艺术到生活,意料,让人耳目一新。



时间: 2024-11-03 01:45:59

<<UML for Java Programmers>> 第11章读书笔记的相关文章

MySQL Cookbook第11章读书笔记

1,创建一个序列列兵生成序列值 使用auto_increment 如果显式地把ID设置成一个非NULL的值,有两个结果: a,这个值在表中出现,由于id列是主键,因而不允许重复,故会出现错误 b,这个值没有出现例如,你的表中id序列值为1到8,此时你插入一个新航,并设置为20,那么下一个自动产生的序列就会从21开始,而9-19的值变得不可用. 2,序列生成的行删除的效果 例如在insect表中: 比如要求只能是昆虫,删除millipede,millbug,多余的蚂蚁 删除2会给序列中间带来一个缺

&lt;java编程思想&gt;第一章读书笔记二

7.伴随多态的可互换对象 前面说了继承,我们知道继承中存在基类(父类)以及导出类(子类),不知道大家有没有遇到过这种情况?就是在向一个方法中传递一个对象作为参数时,我们往往会选择传递一个基类而不是一个子类,为什么要这么做呢?其实原因也很简单,说的高大上一点就是这样做有利于代码的健壮性和可扩展性,说的详细还是有利于代码的健壮性和可扩展性,更重要的也就是可扩展性. 还拿喝可乐的例子来说,如果你传递的参数对象是可乐,那么不管你是给我百事可乐还是可口可乐我都可以接受啊,但是如果你传递的参数仅仅是百事可乐

《Java并发变成实践》读书笔记---第二章 线程安全性

什么是线程安全性 要编写线程安全的代码,其核心在于要对状态访问操作进行管理,特别是对共享的(Shared)和可变的(Mutable)状态的访问.从非正式的意义上来说,对象的状态是指存储在状态变量(例如实例或静态域)中的数据."共享"意味着变量可以由多个线程同时访问,而"可变"则意味着变量的值在其生命周期内可以发生变化.所以编写线程安全的代码更侧重于如何防止在数据上发生不受控的并发访问. 如果当多个线程访问同一个可变的状态变量时没有使用合适的同步,那么程序就会出现错误

UML for Java Programmers之dx实战

dx是一套简单的开发规则.它说白了就是迭代开发,在短周期内迭代处理"所有事情",这里所指的"所有事情"包括需求.分析.设计.实现.测试和文档等等. 它的大概流程是这样:1. 初始探索    跟客户坐下来一起讨论系统到底是做什么的.在这个过程中,识别出系统的use-case也就是我们所说的user-story.一般花两到三天的时间做这件事.2. 功能特征评估 对于每个story,我们给个时间评估,这只是一个纯数字的评估,我们不关心数字的具体单位是什么,对每个story

《Java并发变成实践》读书笔记---第一章 简介

<Java并发编程实战>深入浅出地介绍了Java线程和并发,是一本完美的Java并发参考手册.书中从并发性和线程安全性的基本概念出发,介绍了如何使用类库提供的基本并发构建块,用于避免并发危险.构造线程安全的类及验证线程安全的规则,如何将小的线程安全类组合成更大的线程安全类,如何利用线程来提高并发应用程序的吞吐量,如何识别可并行执行的任务,如何提高单线程子系统的响应性,如何确保并发程序执行预期任务,如何提高并发代码的性能和可伸缩性等内容,最后介绍了一些高级主题,如显式锁.原子变量.非阻塞算法以及

MySQL cookbook第10章读书笔记

1,使用load data和mysqlimport导入数据 1个ok,2个warning!!! 为什么会有warning,而且数据也没有load进去 2,指定数据文件位置 了解MySQL查找文件位置的规则. 如果load data语句没有local选项,MySQL读取数据文件将按下述规则在服务器所在机器上定位文件的位置: 文件的绝对全路径名(从文件系统的根开始),MySQL直接读取该文件. 给定的是文件的相对路径名,按照路径名的两种不同形式来解释和处理. 3,指定数据文件的结构 有一个数据文件但

第七章读书笔记《深入理解计算机系统》

第七章 读书笔记<深入理解计算机系统> 链接是将各种代码和数据部分收集起来并组合成为一个单一文件的过程,这个文件可被加载(或拷贝)到存储器并执行. 链接可以执行于编译时,也就是在源代码被翻译成机器代码时:也可以执行于加载时,也就是在程序被加载器加载到存储器并执行时:甚至执行于运行时,由应用程序来执行. 在早期的计算机系统中,链接是手动执行的.在现代系统中,链接是由叫链接器的自动执行的. 7.1 编译器驱动程序 1.大部分编译系统提供编译驱动程序:代表用户在需要时调用语言预处理器.编译器.汇编器

《Java并发编程实战》读书笔记

Subsections 线程安全(Thread safety) 锁(lock) 共享对象 对象组合 基础构建模块 任务执行 取消和关闭 线程池的使用 性能与可伸缩性 并发程序的测试 显示锁 原子变量和非阻塞同步机制 一.线程安全(Thread safety) 无论何时,只要多于一个线程访问给定的状态变量.而且其中某个线程会写入该变量,此时必须使用同步来协助线程对该变量的访问. 线程安全是指多个线程在访问一个类时,如果不需要额外的同步,这个类的行为仍然是正确的. 线程安全的实例: (1).一个无状

Java 第十二章 继承 笔记

Java 第十二章  继承 笔记 一.使用继承:     1)方便修改代码     2)减少代码量 二.super 继承object 类:super 访问父类的无参构造:super 指的是object 的无参构造.     例:子类调用父类:super.属性 / super.方法    注意:子类不能继承父类私有属性:得用set.get方法来调用:    super只能写在代码块的第一句:super只能调用非私有的方法:    super只能出现在子类的方法和构造方法中. 三.不能被继承的父类成