Feeds:
Posts
Comments

Archive for the ‘Programming’ Category

读书笔记3:Composite

这个比较短。朋友在interview时被问到这个问题,让解释这个Pattern。我想想,好象
我也解释不好,因为觉得会说得太狭义。仔细读了一下,说到底就是刻划一棵树。技巧
上,用到recursive function, 和Null Object。本质还是很简单。

【定义】
Allows you to compose objects into tree structures to represent part-whole
hierarchies. Composite lets clients treat individual objects and
compositions of objects uniformly.

In other words, we can ignore the differences between compositions of
objects and individual objects.

【要点】
– Whole-part relationship
– Tree structure
– Treat uniformly, usually recursive function.
– Not all operations applicable to all objects, NullHandler helps here.

Read Full Post »

Design Pattern笔记:Decorator

这可能是Design Pattern里最简单的之一,但是上次JobHunting版有人问时,仔细想想,发现有些东西其实自己是没想清楚的,所以又读了一遍。

=================================================================

Decorator的核心就是一个operation, 经过一条链来处理,链上的每个环节都可以影响/处理最后的输出。这条链是可以动态增加的。

从结果看,你希望达到的效果就是:
decoratedObj.act()会依次call链上的每一个decorator的act()

要达到这种效果,那每个decorator需要知道:
1. 最初的object的一些公开属性,这可以通过传递object实现
2. 链的上一层处理完的结果,这个通过在act()里递归实现
所以,Decorator需要wrap原来的object, 这个既可以在constructor里实现,也可以通过set***()函数实现,这点跟Inversion of Control(IoC)的实现是一个意思。但个人以为,写在constructor里,实现更清晰易读。

其次,Decorator需要实现act(), 这个实现就是完成自己的任务,然后调用链的上一节
点的act(),形成递归。注意:这个次序是可以改变的,完成自己的任务可以在parent.
act()之前,也可以是之后。

写成code, 大致就是:
public class Decotorator {
protected Component component;
public Decorator(Component component) {
this.component = component;
}
public void act() {
this.component.act();
}
}

把那个JobHunting版的例子改一下就是:

public class Person {
private String name;

public Person() {}

public Person(String name) {
this.name = name;
}

public void show() {
System.out.print(“Decorated person is ” + this.name + “.”);
}

public static void main(String[] args) {
Person p = new Person(“Alice”);
Finery decorated = new TShirt(new BigTrouser(new Sneakers(p)));
decorated.show();
}
}

class Finery extends Person {
protected Person caller;
public Finery(Person caller) {
this.caller = caller;
}

public void show() {
caller.show();
}
}

class TShirt extends Finery {
public TShirt(Person caller) {
super(caller);
}

public void show() {
System.out.print(“TShirt “);
caller.show();
}
}

class BigTrouser extends Finery {
public BigTrouser(Person caller) {
super(caller);
}

public void show() {
System.out.print(“BigTrouser “);
caller.show();
}
}

class Sneakers extends Finery {
public Sneakers(Person caller) {
super(caller);
}

public void show() {
System.out.print(“Sneakers “);
caller.show();
}
}

最后的主函数就是三句:

Person p = new Person(“Alice”);
Finery decorated = new TShirt(new BigTrouser(new Sneakers(p)));
decorated.show();

【典型例子】
Java IO里的:InputStream (base object),FilterInputStream(Decorator) 及其实
现:BufferedInputStream, DeflatorInputStream, InflaterInputStream,
LineNumberInputStream, PushbackInputStream etc.

FileInputStream, StringBufferInputStream, ByteArrayInputStream则是
InputStream的实现。

【附记】
Decorator和Chain of Responsibility的区别,后者是链上的某一个环节,把发来的请
求处理了,就返回;不处理,就扔给下一个环节。

【副作用】
* Decorator可能导致很多小class,每一个都只是功能的一部分实现。
* Decorator可以动态添加,该用多少,互相之间有什么影响,这些动态因素可能影响
将来的维护。尤其是如果Decorator里有任何的假设,或者dependency,将来很可能不经意地引入bug。

Read Full Post »

解题的误区

不是所有的题都要自己解出来才是进步。那是一种非常慢的进步。如果你能读懂解答,那也是一种进步,而且是一种非常有效率的进步。

解题限制:三天时间,如果三天解不出,找到答案,读懂它。

Read Full Post »

Management notes

  • Try to fill in others’ shoes, you can understand better at what you are doing now. Work as tester to find why debug information is important; work as programmer to understand why change is not that easy.

Read Full Post »

Programming Notes

  • Zero-tolerance to misleading debug information
  • Where do you need debug information? where crazy data could possibly comes in.
  • For complex function, debug at lower level, as simple as you can; test at both low level and high level, as complicate as you can.

Read Full Post »

Debug

If you can simplify(single out) the problem, you solve half of it;

if you can build a simple test, you solve another half.

Read Full Post »

Please, blame yourself ONCE more.

I run a Maven build through Tomcat servlet. It must be Tomcat cause this stupid error: svn cannot move .svn/tmp/entries to .svn/work/entries, Access is denied.

Proof 1: If I run mvn update from command line, everything is fine.
Proof 2: If I run mvn deploy from command line, subversioned code is updated and compiled, deployed fine.
Proof 3: When error happens, I run mvn clean, it reports error: cannot delete file, actually, that file is locked by Tomcat. If I shut down Tomcat, I can mvn clean it.
Do you need more proof to show that Tomcat is the culprit?

Wait, this is a long wait, which actually takes 1 month for me to realize: that file looks like locked by Tomcat, but actually is by my own servlet code. When I check whether the branch is the same, I open that file handle and forget to close it! Normally, Java will close it after method call, in garbage collection. But the timing is not guaranteed.

Oh well, again, it is ME who should get blame.

Read Full Post »

Older Posts »