Effective Java阅读笔记-item13、14
Dreamhead把他用大把银子买来的“Effective Java”借给我阅读,我真是很感动亚,我只能用行动来感谢Dreamhead了。^_^
13、支持不变性(immutable)
我感觉我们只需记住书中列出的几条规则:
1. 不要提供任何"可修改对象內容"的方法
2. 保证没有可被子类override的方法
3. 令所有field为 final
4. 令所有field都是 private
5. 保证对任何可变组件的互斥存取
Immutable object优点:
- Immutable object本质上是线程安全的,不需要同步
- Immutable object可以被自由的share
- Immutable object对于其他对象来说,形成了很多构件
缺点:对于每一个不同的值,都要形成一个独立的object
如:
String newStr = “AB”+”CD”;
这样可能会带来的是效率问题。
14、复合(composition)优先于继承(extends not implements)
在本Item中,作者针对安全继承提出几个观点:
- 包内继承很safe,因为super class和sub class都在一个Programmer的control下。
- 继承自专门为继承而设计并有很好的文档的类也很安全。
相反越界继承就是不安全的。
关于继承的几个观点:
- 继承打破的封装性;
- 当subclass确实是superclass的子类型的时候,也就是确实是“is a”的关系时才使用继承。
继承将会传播 superclass API 的所有缺陷,而复合允许你设计新的 API,隐藏 superclass 的缺陷。
书里还提到了composition vs delegete的概念,以前我对delegate的概念也不是很清楚,这次正好顺便好好分析一下:
以书中的代码为例:
public class InstrumentedSet implements Set {
private int addCount = 0;
… …
public InstrumentedSet(Set s) {
this.s = s;
}
}
针对这段代码作者观点:“有时,复合(composition)和转发(forwarding)这两项技术的结合被错误地引用为“委托(delegation)” 从技术的角度而言,这不是委托(delegation),除非包装对象把自己(InstrumentedSet)传递给一个被包装的对象(Set)”
关于delegate:GOF那本书中如是说“Delegation is a way of making composition as powerful for reuse as inheritance [Lie86, JZ91]. In delegation, two objects are involved in handling a request: a receiving object delegates operations to its delegate. This is analogous to subclasses deferring requests to parent classes. But with inheritance, an inherited operation can always refer to the receiving object through the this member variable in C++ and self in Smalltalk. To achieve the same effect with delegation, the receiver passes itself to the delegate to let the delegated operation refer to the receiver 。
The main advantage of delegation is that it makes it easy to compose behaviors at run-time and to change the way they're composed”。
下面的代码改自某论坛上一个网友的代码,我自己觉得这段代码对于正确理解delegate很有帮助。
Considering the following code:
//MyDelegatee.java
public class MyDelegatee {
void methodB() {
}
}
//MyDelegate.java
public class MyDelegate {
MyDelegatee delegatee;
void methodA() {
delegatee.methodB();
}
}
上面的代码就不是delegate,而是composition和forwarding,因为MyDelegate直接调用了MyDelegatee object的方法,这只是forwarding methods。
//MyDelegatee.java
public class MyDelegatee {
void methodB(MyDelegate delegate) {
delegate.do();
}
}
//MyDelegate.java
public class MyDelegate {
MyDelegatee delegatee;
void methodA() {
delegatee.methodB(this);
}
void do(){
}
}
MyDelegate已经把自身pass给了MyDelegatee,并且MyDelegatee调用了MyDelegate的方法,这是一种indirection。也就是说delegatee一定会调用delegate的某些方法,因此你首先得把delegate传递给delegatee。
我们在举个实际一点的例子,董事长和总经理的故事:
Considering the following code:
//Chairman.java
public class Chairman {
private GeneralManager gm = new GeneralManager();
public void doThroughGM(){
gm.investmentDecisionMaking(this);
}
//董事长拥有的权利
public void investmentDecisionMaking(){
/*
*董事长具有战略投资决策权,
*董事长可将此权利授权给总经理
*/
System.out.println("总经理被授权执行投资决策");
}
public static void main(String[] args) {
Chairman chairman = new Chairman();
chairman.doThroughGM();
}
}
//GeneralManager.java
public class GeneralManager {
public void investmentDecisionMaking(Chairman chairman){
//总经理被授权获得的权利
chairman.investmentDecisionMaking();
}
}
//output:
总经理被授权执行投资决策
上面的例子模仿了一个现实世界的过程,在现实世界中,假如董事长把权利授权给总经理,总经理一定会获取董事长才拥有的权利,它会利用这些权利来替公司做事。
举了这些例子后对delegate有些概念了吧^_^。
参考资料:
1、http://www.javaworld.com/javaworld/javaqa/2001-09/01-qa-0914-delegate.html
2、http://forum.javaeye.com/viewtopic.php?t=6120
评论