相關讀書筆記列表
前言: 清晰性和簡介性是最為重要的
一個模組的使用者永遠也不應該被模組的行為所迷惑(那樣就不清晰了),模組要儘可能的小,但又不能太小【術語模組(module):是指任何可重用的軟體組件,從單個方法到包含多個包的複雜系統都可以是一個模組】。代碼應該被重用,而不是拷貝,模組之間的相依性應該儘可能降低到最小,錯誤應該儘早被檢測出來,理想的情況下是在編譯的時刻。
NO.1
考慮用靜態Factory 方法代替建構函式
靜態Factory 方法好處:
①建構函式有命名的限制,而靜態方法有自己的名字,更加易於理解。
②靜態Factory 方法在每次調用的時候不要求建立一個新的對象。這種做法對於一個要頻繁建立相同對象的程式來說,可以極大的提高效能。它使得一個類可以保證是一個singleton;他使非可變類可以保證“不會有兩個相等的執行個體存在”。
③靜態Factory 方法在選擇傳回型別時有更大的靈活性。使用靜態Factory 方法,可以通過調用方法時使用不同的參數建立不同類的執行個體,還可以建立非公有類的對象,這就封裝了類的實現細節。
靜態Factory 方法壞處:
①如果一個類是通過靜態Factory 方法來取得執行個體的,並且該類的建構函式都不是公有的或者保護的,那該類就不可能有子類(被繼承),子類的建構函式需要首先調用父類的建構函式,因為父類的建構函式是private的,所以即使我們假設繼承成功的話,那麼子類也根本沒有許可權去調用父類的私人建構函式,所以是無法被繼承的
。
②畢竟通過建構函式建立執行個體還是SUN公司所提倡的,靜態Factory 方法跟其他的靜態方法區別不大,這樣建立的執行個體誰又知道這個靜態方法是建立執行個體呢?彌補的辦法就是:靜態Factory 方法名字使用valueOf或者getInstance.
總結:靜態Factory 方法和公有的建構函式都有他們各自的用途,我們要理解他們各自的長處,避免一上來就用建構函式,通常靜態工廠更加合適。如果沒有其他因素強烈的影響我們的選擇,最好還是簡單的選擇建構函式,畢竟他是語言提供的規範。
NO.2
試用私人建構函式強化singleton屬性
實現singleton的方法有兩種:
方法一:公有的靜態成員是一個final域,成員的聲明很清楚的表達了這個類是一個singleton。
public class Elvis {</p><p> public static final Elvis INSTANCE = new Elvis();</p><p> private Elvis() { }</p><p> public void leaveTheBuilding() {</p><p> System.out.println("Who a baby, I'm outta here!");</p><p> }</p><p> // This code would normally appear outside the class!</p><p> public static void main(String[] args) {</p><p> Elvis elvis = Elvis.INSTANCE;</p><p> elvis.leaveTheBuilding();</p><p> }</p><p> }
方法二:提供一個公有的靜態方法,而不是公有的靜態final域。該方式提供了更大的靈活性,在不改變API的前提下,可以把該類改成singleton或者非singleton的。
public class Elvis {</p><p> private static final Elvis INSTANCE = new Elvis();</p><p> private Elvis() { }</p><p> public static Elvis getInstance() { return INSTANCE; }</p><p> public void leaveTheBuilding() {</p><p> System.out.println("Who a baby, I'm outta here!");</p><p> }</p><p> // This code would normally appear outside the class!<br /> public static void main(String[] args) {</p><p> Elvis elvis = Elvis.getInstance();</p><p> elvis.leaveTheBuilding();<br /> }<br /> }
一般來說,第一種方法效率稍微高一些,然後,採用第一種方法實現singleton後,就沒有改變的餘地了,當你想把該類改成非singleton,顯然是不行的了。所以,除非確實確定該類是一個singleton,那就用第一個方法吧。用第2種方法的時候,假如該類實現了serializable介面,那應該重寫(override)readResolve()方法,否則再還原序列化的時候是會產生一個新的執行個體,這與singleton相違背了!
NO.3
通過私人的建構函式強化不可執行個體化的能力
在物件導向程式設計中,假如存在太多隻有靜態屬性和靜態方法的類;那麼,物件導向的思想可能在這會損失殆盡。但是,並不能說物件導向的程式中就不應該出現只有靜態屬性和靜態方法的類,相反,有時候我們還必須寫這樣的類作為工具類。這樣的類怎麼實現呢?有人可能會把該類定義成抽象類別(Abstract
class),的確,抽象類別是不可以執行個體化的,但是別忘了還有繼承,繼承了抽象類別的子類在執行個體化時候,預設是會先調用父類無參數的建構函式的(super();),這時候,父類不是也被執行個體化了嘛?其實我們可以這樣做,把該類的建構函式定義為私人的(private),而類的內部又不調用該建構函式的話,就成功了。這樣帶來的後果就是該類成了
final的,不可能再被任何類繼承了,要被繼承,得提供一個公有(public)的或者保護(protect)的建構函式,這樣才能被子類調用。