Item 12:把類和成員的可訪問范圍降到最低
好的模塊設計應該盡最大可能封裝好自己的內部信息,這樣可以把模塊之間的耦合程度降到最低。開發得以并行,無疑這將加快開發的速度,便于系統地維護。Java中通過訪問控制符來解決這個問題。
你在設計一個類的時候應該盡量的按照4321得順序設計。假如一個類只是被另一個類使用,那么應該考慮把它設計成這個類的內部類。通常public的類不應該有public得字段,不過我們通常會用一個類來定義所有的常量,這是答應的。不過必須保證這些字段要么是基本數據類型要么引用指向的對象是不可修改的。不然他們將可能被修改。例如下面的定義中data就是不合理的,后面兩個沒有問題。
public class Con
{
public static final int[] data = {1,2,3};// it is bad
public static final String hello = "world";
public static final int i = 1;
}
Item 13:不可修改的類更受青睞
不可修改的類意思是他們一經創建就不會改變,例如String類。他們的設計、實現都很方便,安全性高——它們是線程安全的。設計不可修改類有幾點規則:
Item 14:化合(合成)比繼續更值得考慮
實現代碼重用最重要的辦法就是繼續,但是繼續破壞了封裝,導致軟件的鍵壯性不足。假如子類繼續了父類,那么它從父類繼續的方法就依靠父類的實現,一旦他改變了會導致不可猜測的結果。作者介紹了InstrumentedHashSet作為反例進行說明,原因就是沒有明白父類的方法實現。作者給出的解決辦法是通過化合來代替繼續,用包裝類和轉發方法來解決問題。把想擴展的類作為本類的一個private final得成員變量。把方法參數傳遞給這個成員變量并得到返回值。這樣做的缺點是這樣的類不適合回掉框架。繼續雖然好,我們卻不應該濫用,只有我們能確定它們之間是is-a得關系的時候才使用。
Item 15:假如要用繼續那么設計以及文檔都要有質量保證,否則就不要用它
為了避免繼續帶來的問題,你必須提供精確的文檔來說明覆蓋相關方法可能出現的問題。在構造器內千萬不要調用可以被覆蓋的方法,因為子類覆蓋方法的時候會出現問題。
import java.util.*;
public class SubClass extends SuperClass
{
private final Date date;
public SubClass()
{
date = new Date();
}
public void m()
{
System.out.println(date);
}
public static void main(String[] args)
{
SubClass s = new SubClass();
s.m();
}
}
class SuperClass
{
public SuperClass()
{
m();
}
public void m()
{
}
}
由于在date被初始化之前super()已經被調用了,所以第一次輸出null而不是當前的時間。
由于在Clone()或者序列化的時候非常類似構造器的功能,因此readObject()和clone()方法內最好也不要包括能被覆蓋的方法。
Item 16:在接口和抽象類之間優先選擇前者
接口和抽象類都用來實現多態,不過我們應該優先考慮用接口。知道嗎?James說過假如要讓他重新設計java的話他會把所有都設計成接口的。抽象類的優點是方便擴展,因為它是被繼續的,并且方法可以在抽象類內實現,接口則不行。
新聞熱點
疑難解答