`

《agile java》读书笔记

    博客分类:
  • Book
阅读更多


这是一本学习驱动测试的java好书, 里面在讲java的各种知识均采用TDD的方式, 是一本不错的TDD实战书。 在掌握Java知识的同时也领略了TDD的开发方式。
这本书比较厚, 断断续续也看了很久。 今天总算看完了, 里面讲重构, 讲设计原则, 对平时的开发, 测试都有不错的借鉴意义。 比较遗憾的是没有按照里面的做法一一实践, 因此难免造成“纸上得来终觉浅”。
这本书我最大的收获就是: 除了开发代码需要重构, 测试代码也需要重构, 一开始不要做最完美的实现, 一开始的重复不可怕, 一开始的丑陋不可怕, 只有能实现我们需要的功能即可, 在有单元测试做保证之后再一一进行重构逐步得到理想的代码.

保持代码的简单, 干净:
确保测试是完备的, 而且总是运行成功
消除重复
保证代码是干净和富有表现力的
将类和方法的数量减少到最小

设计系统, 通过扩展来拥抱变化, 不要通过修改来拥抱变化

代码中不应该有大量的switch语句, 而且也不应该包含大量的多重if语句. 通常可以采用多态来消除switch语句.

使用递归一定要注意递归的终止条件, 如果递归中没有终止条件, 那么会导致无限递归调用. 所以递归中需要防卫子句.

Math

BigDecimal对象是不可变的, 当发送add消息到BigDecimal时, 不会改变对象的值, add方法会取出参数, 与BigDecimal对象相加, 然后创建并返回一个新的表示总和的BigDecimal对象

使用位操作来存储多个标志位, 是一种经典的技术, 该技术在给定内存的条件下, 最大程度的进行了信息的压缩. 因为java通过数组或者其他包含boolean值的集合, 提供了更清晰简单的表示方法, 所以不体检, 也没有必要在java开发中使用该技术

异或运算是奇偶校验的基础, 在数据传输中, 可能会有若干数据位失真, 奇偶校验对发送的数据进行异或运算, 从而计算出校验和, 并将校验作为附加信息发送出去, 接收方针对数据进行同样的计算, 如果校验和不匹配, 那么发送方需要重新发送数据.

如果数据流中1的位数是偶数, 那么校验位就是偶数, 如果数据流中1的个数是奇数, 那么校验位就是奇数.

对偶数个1进行异或运算, 结果总是偶校验(0), 对奇数个1进行异或运算, 结果总是奇校验(1)

异或运算相当于对两个数字进行相加, 然后对2求余运算, 对2求余其结果要么是0, 要么是1

线程
分清线程或者线程的执行与Thread对象之间的区别, 是非常重要的, 线程是线程调度器所管理的一段控制流程. Thread是一个管理有关线程执行信息的对象. 一个Thread对象的存在并不意味着一个线程的存在, 知道Thread对象启动, 线程才会存在, 而且Thread对象可以在线程结束之后存在很长时间

对于需要频繁在列表尾部 的其他地方进行删除或插入操作的集合来说, LinkedList较ArrayList会提供更好的性能.

当线程阻塞在IO操作或者被挂起时, 可以通过显式的调用yield方法或者进入睡眠, 来让出时间, 比如在线程的run方法中每次迭代会调用yield方法来让其他线程得到机会执行
public void run(){
   while(true){
	if (queue.isNotEmpty()){
		execute(queue.remove(0));
		Thread.yield();
	}
   }
}


线程并不位于java语言级别, 而是位于语句被翻译后由VM执行的更底层的级别. 你在java中编写的大部分语句都是非原子的: 许多诸如增加计数器或者给一个引用赋值这样简单的事情, java编译器都可能会创建若干内部操作来对应这一条语句. 假定一个赋值语句会耗费两个内部操作. 第二操作在线程调度器在挂起该线程并执行第二个线程之前, 可能还没有完成. 所有这种代码的交错, 意味着你可能会遇到同步的问题, 如果两个线程均在同一时间访问同一段数据, 结果可能是你无法预料的.

synchronized相当于对一块代码片段加锁. java使用一种称为监视器的概念来保护数据, 每个对象都关联有一个监视器, 这个监视器保护对象的实例数据. 该监视器同每个类相关联, 他保护类的静态数据. 当你获得一个锁的时候, 你同时也获得了相关联的监视器, 任何给定的时刻, 只有一个线程可以获得一个锁. 通常在synchronized关键字后面的括号中指定一个对象来作为监视器.

java.util.concurrent包中提供了很多实用类来帮助我们解决很多有多线程的问题, 当然你应该首选使用这个库, 但他的存在并不意味着你不需要学习线程背后的基本原理和概念, 就如同你在使用计算器解决所有计算之前需要学习好乘法如何工作一样

BlockingQueue为队列添加了与同步相关的能力. 举例来说, 包括在取出下一个元素时等候其出现的能力, 以及在保存元素时等待有空间空闲的能力.

LinkedBlockingQueue的put方法将元素添加到队列的尾部. take方法从队列的开始处删除一个元素, 他还会等待, 直至队列中有元素存在.

解决死锁的方案:
1.在要上锁的对象排定次序, 并保证在获得锁时使用相同的次序
2.锁住一个共同的对象.

泛型
java的泛型采用了一种叫擦拭法, 不同于创建一个独立的类型定义, java擦拭了参数化类型的信息, 并创建一个单一的等效类型, 每个类型参数与一个成为它的上限(upper bound)的约束相关联, 缺省是Object. 客户端的绑定信息被擦除, 并替换为适当的强制转型类型.

类似这样的定义List<Object> list, 通过将list绑定到Object, 你会限定它只能保存Object类型的对象, 而且不能是Object的任何子类型, 比如不能将List<String>的引用赋值给list

如果对参数类型是采用的通配符表示的, 比如List<?> 或List<? extends Number>, 会存在一个缺点, 你不能调用类型参数对象中的方法.

对于这样的方法pad(List<?> list, Object element)用来将element插入到list中, java会有编译错误, 因为通配符?指示了一个未知的类型, 这样pad方法对于传入的对象的特定类型并不知情. 这样调用方可能传入非法类型破坏类型安全.

由于采用擦拭法的原因, java无法判断某个给定的操作是否是安全的, 因此它只有全部禁止他们, 一般的经验法则是, 只有从数据结构读取时, 你可以使用有界(bounded)的通配符

而采用泛型方法可以解决这样的问题, 比如<T> pad(List<T> list, T element), 编译器可以根据传递给pad的参数, 提取或推断出T的类型, 他能够从参数中推断出的最确切的类型.

jdk中一个比较复杂的泛型
public static <T extends Comparable<? super T>> T max(Collection<? extends T> c)

max接受一个任意类型的对象的集合, 但这个类型必须实现了Comparable接口, 且这个类型必须是在集合中存储的元素所绑定的类型或者父类. 经过擦拭之后得到:
public static Comparable max(Collection c)

而我们知道早期的非泛型版本是
public static Object max(Collection c)

因此破坏了兼容性, 但使用附加界限能有效解决这个问题:
public static <T extends Object&Comparable<? super T>> T max(Collection<? extends T> c)

因为J2SE规范中规定, 一个类型变量会被擦除为他最左边的界限, 这里就是Object, 而不是Comparable. 不过返回的对象定义了附加的限制, 即收集的对象必须实现适当的Comparable接口.

由于擦拭法的原因, 参数化类型的对象没有关于绑定类型的信息. 对于你可以和不可做什么, 产生了许多隐含的影响.
比如这样:
public class NumberList<T extends Number>{
public void init(){
T zero = new T(0);
...
}
}
擦拭意味着裸类型(T)擦去了其上限(Number), 在多数情况下, 上限是一个抽象类, 因此创建这样的类型变量无意义或非法. java简单的禁止了这种操作. 而且T也不能参与instanceof 操作符处理.

注解
一个关于复式注解的例子
classIgnoreDateTest{
	@Ignore
	(
		initialize = TestRunnerTest.IGNORE_INITIALS,
		date = @Date(month = 1, day = 2, year = 2010)
	)
	public void test(){...}
}

其定义为:
public @interface Date{ int month(); int day(); int year();}

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Ignore{String[] reasons(); String initialize(); Date date();}

因为Date注解类型只是作为另一个注解的一部分, 不需要指定保留度(retention)或目标(target)

关于注解的额外注意事项
  • 没有指定target的注解可以修饰任何java类型
  • 在注解类型声明中, 唯一你可以返回的参数化类型是Class类型
  • @Document元注解类型可以让你声明将某个注解类型包含在由javadoc等工具产生的api文档ongoing
  • @Inherited元注解意味着一个注解类型是被所有子类型继承的. 如果你调用Method或Class对象的getAnnotation方法而不是getDeclareAnnotation方法, 便可以返回他.
  • 你不能将null作为注解的值
  • 你不能用一个给定的注解来重复的修饰某个元素.
  • 为了在内部支持注解类型, sun修改了Array类, 加入了toString和hashCode()方法的实现


谨慎地使用注解类型, 注解类型是一个接口, 并且应该表示一种稳定的抽象, 同其他接口一样, 确保你已经仔细考虑在系统中引入注解类型所带来的影响.

正则表达式
从Pattern对象中, 你可以为指定的输入String得到Matcher对象, 在你得到Matcher对象之后, 你可以调用它的find方法来得到下一个子串, 如果发现匹配, find方法返回true, 否则返回false.

Matcher实例保存了有关上一个被发现的子串的信息, 你可以调用Matcher对象的start和end方法来得到描绘匹配子串的索引, 调用Matcher的group方法可以得到匹配的子串文本.

Matcher的matches方法, 如果整个输入字符串匹配了某个表达式, 它会返回true, 你还可以调用lookingAt, 当输入字符串的开始处和正则表达式匹配时, 它会返回true.

native表示这个方法是在jvm中实现的, 而不是java中实现的.

协变(covariance)指的是这样一种能力: 子类方法返回一个对象, 其类型为父类定义的返回类型的子类, clone是java协变的一种典型示例.

分享到:
评论
2 楼 itpengweieye 2012-10-17  
我也有兴趣买这本书,本人也在杭州
1 楼 heven0818 2012-01-20  
我想买这书,有兴趣转让不?

相关推荐

    Agile Java学习笔记【二】

    在本篇“Agile Java学习笔记【二】”中,我们将深入探讨敏捷开发方法与Java编程的结合,以及如何在Eclipse集成开发环境中利用Ant工具进行构建和测试。敏捷开发是一种以人为本、迭代、逐步发展的软件开发方法论,强调...

    Agile Java Crafting Code with Test-Driven Development

    Agile Java Crafting Code with Test-Driven Development英文版,包含pdf和chm格式,pdf格式的目录缩进和超连接有问题,所以附上了改造过的chm文件,以便有心人可以修改目录。

    agile java 课程源码

    agile java 每一章 课程 的 源码;

    Agile Java 中文版

    通过阅读《Agile Java 中文版》,读者不仅可以掌握Java编程技能,还能了解到敏捷开发的思维方式,这对在快速变化的IT环境中开发高质量软件至关重要。无论你是初学者还是有一定经验的开发者,这本书都能提供有价值的...

    Agile Java Example Code

    【标题】"Agile Java Example Code" 涵盖了敏捷开发方法在Java编程中的实践应用,这是一系列示例代码,旨在展示如何在实际项目中采用敏捷原则和技巧。敏捷开发是一种以人为本、迭代和增量的软件开发方法论,强调快速...

    《Agile Java》中文版

    通过阅读《Agile Java》中文版,读者不仅可以掌握Java编程语言,还能了解到敏捷开发的思维方式,这对于想要从事软件开发的初学者来说是一份非常全面的指南。书中的实例和练习将帮助读者巩固理论知识,提高实践能力,...

    agile Java课后习题代码

    通过阅读和分析这些代码,我们可以学习到如何将敏捷开发理念融入到Java编程中,比如如何编写可测试、可维护的代码,如何实现模块化设计,以及如何运用设计模式等。 在这个项目中,可能包括以下内容: 1. **单元测试...

    Agile Java 高清中文版

    Agile Java 高清中文版 这本书一大特点是以单元测试和TDD来贯穿全书的,在教你Java各种重要的基础知识的过程中,潜移默化的影响你的编程思维走向敏捷,走向TDD。这本书成书,以JDK5.0的语法为基础讲解,要学习JDK...

    Agile Java 高清中文版.rar

    《Agile Java 高清中文版》是一本深入...通过阅读《Agile Java 高清中文版》,读者不仅可以深入了解Java编程,还能学习到敏捷开发的精髓,从而在实际工作中更好地应对复杂的需求变化,提高团队的开发效率和产品质量。

    agileJava 程序代码

    首先,我们要理解"AGILE"(敏捷)在软件开发中的含义。敏捷开发是一种以人为本、迭代、增量的开发方法,强调快速响应变化,通过持续交付有价值的软件来满足客户需求。它倡导灵活的规划、迭代的工作节奏以及团队间的...

    agile java(CHM)

    通过阅读《Agile Java》,开发者可以学习到如何将敏捷开发原则和TDD实践融入到日常的Java编程工作中,从而提升项目的效率和代码质量。这本书对于想要提升自身技能,特别是对TDD感兴趣的Java开发者来说,是一份非常...

    agile java 课本及课后代码

    《敏捷Java》是一本专注于Java编程和敏捷开发实践的书籍,其核心理念是结合敏捷开发方法与Java技术,提升软件开发效率和质量。书中的课后代码提供了丰富的实例,帮助读者深入理解和应用所学知识。以下是对这本书及其...

    ( 2 agile java.pdf

    ### 敏捷Java:通过测试驱动开发...通过阅读本书,读者不仅可以掌握Java编程的核心技能,还能学会如何运用敏捷方法论来提高软件开发的效率和质量。无论你是Java初学者还是有一定经验的开发者,都能从这本书中受益匪浅。

    Agile Java 习题3,4--类方法和类变量

    本话题将深入探讨Agile Java中的类方法和类变量,这些是面向对象编程的基础概念,对于理解和编写高质量的Java代码至关重要。 类方法和类变量是Java类的核心组成部分。在Java中,类是创建对象的蓝图,它定义了对象的...

    Agile Java Development with Spring, Hibernate and Eclipse-code

    书中的代码示例涵盖了Java开发的重要方面,结合了Agile开发理念、Spring框架、Hibernate持久化库以及Eclipse集成开发环境的实用技巧。 Agile开发是一种以人为核心、迭代、逐步交付的软件开发方法论,强调快速响应...

    Agile Java Development with Spring, Hibernte and Eclipse

    综上所述,《敏捷Java开发》是一本全面介绍Spring、Hibernate框架和Eclipse IDE在敏捷Java开发中的应用的书籍,涵盖了从技术细节到开发实践的各个方面,非常适合希望提升Java开发技能的读者阅读。

    AgileJava教程课本代码

    《AgileJava教程课本代码》是一份非常宝贵的资源,它包含了《AgileJava》一书中的所有源代码。这本书在Java编程领域具有很高的知名度,是许多开发者学习和提升敏捷开发技能的重要参考。AgileJava教程强调了敏捷开发...

Global site tag (gtag.js) - Google Analytics