Lenshood

Software Developer @ThoughtWorks

0%

使用和避免使用 null

"null 烂透了“ - Doug Lea "这是我犯得值 10 亿刀的错误" - Sir C. A. R. Hoare 提到他发明的 null 时如是说

null的粗心使用会导致各种各样令人难以置信的错误。对 Google 的基础代码进行研究后,我们发现大约 95% 的集合中都不应有任何 null 值,如果对 null 快速失败而不是默默地接受,便会对开发者有所帮助。

此外,null 也会产生令人不悦的模糊情况。通常很少有能准确的揣摩到返回null值原本意义场景,例如,当 Map.get(key)返回null 时,一种可能是 key 对应的值本来就是null,而另一种情况则是该 key 并不存在。Null 能代表失败,能代表成功,能代表几乎任何事。如果能用其他的值来代替null,会使表意更加清晰。

即便如此,有些时候使用 null 仍旧是正确合理的。从内存占用和速度角度讲,null 非常划算,而且不可避免的会在对象数组中使用。然而,相较于库代码,在应用代码中, null 是造成逻辑困扰、难以理解的 bug 以及令人不悦的模糊的主要来源。例如,当 Map.get 返回 null 时,null 可能代表值不存在,或者值存在且等于 null。最要命的,null 不会对他所代表的的意义给出任何提示。

由于上述原因,大多数 Guava 工具都设计为只要能找到 null 的替代方案,就对 null 采取快速失败处理,不允许使用 null。此外,Guava 提供了许多工具,让你在必须使用 null 的时候能更简单,也能帮助你避免使用 null

Read more »

并发编程是 Java 编程的基础,同时也是提升效率,改善性能表现的利器。说到并发,就一定会说到同步,synchronized关键字是 Java 中关于同步最基础的设计,它能够简单明确的提供对变量、代码块、方法、类的同步支持。我们大都知道,同步能够为代码提供原子性,但有时我们会忽略,同步还有一个重要的作用,就是提供了代码的可见性。

下文将从两个方面,以 Java 为例简述同步带来的原子性和可见性,并在可见性部分引出了经常令 Java 程序员困惑的 volatile关键字。

Read more »

There's a very simple routine in the book: Clean Code, Chapter 6, page 96

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class Square {
public Point topLeft;
public double side;
}

public class Rectangle {
public Point topLeft;
public double height;
public double width;
}

public class Circle {
public Point center;
public double radius;
}

public class Geometry {
public final double PI = 3.141592653589793;
public double area(Object shape) throws NoSuchShapeException
{
if (shape instanceof Square) {
Square s = (Square)shape;
return s.side * s.side;
}
else if (shape instanceof Rectangle) {
Rectangle r = (Rectangle)shape;
return r.height * r.width;
}
else if (shape instanceof Circle) {
Circle c = (Circle)shape;
return PI * c.radius * c.radius;
}
throw new NoSuchShapeException();
}
}
As a OO programer, what a ugly code! That code are totally no object-oriented, and use such a if...else... structure to deal with different classes rather than using polymorphic. However, uncle bob said at the follow: > Consider what would happen if a perimeter() function were added to Geometry. The shape classes would be unaffected! Any other classes that depended upon the shapes would also be unaffected! On the other hand, if I add a new shape, I must change all the functions in Geometry to deal with it. Again, read that over. Notice that the two conditions are diametrically opposed.

So the concept of Data Structure and Object are come out: > Procedural code (code using data structures) makes it easy to add new functions without changing the existing data structures. OO code, on the other hand, makes it easy to add new classes without changing existing functions.

Procedural code makes it hard to add new data structures because all the functions must change. OO code makes it hard to add new functions because all the classes must change.

But again, as a OO programer, I can't take this, I want to deal with the scenario of change behavior more "elegantly".

Then Uncle bob jump out again and say: try Vistor pattern! (you can find it at the footnote in page 96)

Read more »

码字利器 提升快感

Intellij Idea 作为写 Java 最爽、最快、最智能的 IDE,其丰富的功能和完善的快捷键让 Java Coder 可以完全采用键盘流的方式写代码,并且做各种额外的事情(包括在终端跑命令、VCS、文件操作等等)都不用切出 IDE。

在使用的时候完全感觉不到它的存在,才是最棒的工具,Idea 可以做到这一点,Vim 也能做到这一点,这两种完全不同的 editor 用习惯了后都能手随心动,行云流水,优秀的 editor 更容易让使用者进入 心流(flow) 的工作状态。

相比之下,Idea 的优势在于能够快速的在 interface、实现类、方法等等之间跳转,能够方便快速的重构,及通过代码模板自动生成样板代码;Vim 的优势在于高效的文字编辑、处理能力。在Idea 编码的时候经常会不由自主的想要按一下 gg 或是 jk 等等 Vim 的按键来快速的回到页首或是上下移动。

实际上,IdeaVim 作为 IntellliJ Idea 的插件,能实现快速的在 Idea 中使用 Vim 的能力,结合二者的优势,让编码更顺滑。

Read more »

由于某些神秘的原因,某些理所当然的数值计算,通过编程语言操作时,会让人匪夷所思。也是因为这些神秘的原因,业务中常见的集星星、代币值、金额计算等场景中,有可能会出现一长串和期望值有微小偏差的数值(尤其是前后端传递数值的时候..)

Read more »

本文非原创,是对英文原文的译文,原文请见:Notes on Reactive Programming Part I: The Reactive Landscape

响应式编程是一种非常有趣的编程思想,目前对于响应式编程,存在诸多的文章、杂谈,然而对于局外人或是从事简单企业项目开发的 Java 开发者而言(比如笔者),这些内容并不都容易理解。本文(系列第一篇)没准能帮你理清这些杂乱,文章的内容已经尽可能的具体,绝不会出现指代语义的情况。当然,如果你想要的是更加学术的论述以及 Haskell 语言的代码示例,那就 Google 一下吧,本文并不涉及这些。

响应式编程经常与并发编程、高性能等概念相混淆,以至于难以将这些概念分清,实际上在原理上他们完全不同。不可避免的,这肯定会导致混乱。响应式编程经常与函数式反应编程(FRP)相互交融(或直接就被称作是 FRP)。一些人认为响应式编程没什么新奇的,他们每天都这么干(这些人通常都使用 JavaScript 进行开发)。另一些人认为,响应式编程是微软带给人间的礼物(在先前微软在发布一些 C# 的 extension 时引起了巨大的轰动)。而在 Java 企业应用领域,近期已经有了一些风吹草动(见Reactive Streams initiative),就像任何其他的新生事物一样,在何时何地使用的问题上,还存在许多容易犯的错误。

Read more »