面向對象
01、構造器參數太多怎么辦?
如果參數很多,會導致構造方法非常多,拓展性差,代碼難編寫,且難以看懂。
用JavaBeans模式,
get和set
一行構造編程多行代碼實現,需要使用額外機制確保一致性和線程安全。
用builder模式,
1、5個或者5個以上的成員變量
2、參數不多,但是在未來,參數會增加
Builder模式:
屬於對象的創建模式,一般有
1、 抽象建造者:一般來說是個接口,包含1)建造方法,建造部件的方法(不止一個),2)返回產品的方法
2、 具體建造者
3、 導演者,調用具體的建造者,創建產品對象
4、 產品,需要建造的復雜對象
對於客戶端,創建導演者和具體建造者,並把具體建造者交給導演者,然后由客戶端通知導演者操縱建造者進行產品的創建。
在實際的應用過程中,有時會省略抽象建造者和導演者。
優勢:如果當大多數參數是可選時,代碼易於閱讀和編寫,比JavaBean更加安全。
02、不需要實例化的類應該構造器私有
如,一些工具類提供的都是靜態方法,這些類是不應該提供具體的實例的。可以參考JDK中的Arrays。
好處:防止使用者new出多個實例。
03、不要創建不必要的對象
1、 避免無意中創建的對象,如自動裝箱
可以在類的多個實例之間重用的成員變量,盡量使用static。
性能對比。
但是,要記住,是不要創建不必要的對象,而不是不要創建對象。
對象池要謹慎使用,除非創建的對象是非常昂貴的操作,如數據庫的連接,巨型對象等等。
04、避免使用終結方法
finalizer方法,jdk不能保證何時執行,也不能保證一定會執行。如果有確實要釋放的資源應該用try/finally。
05、使類和成員的可訪問性最小化
模塊對外部其他模塊來說,隱藏其內部數據和其他實現細節——封裝
編寫程序和設計架構,最重要的目標之一就是模塊之間的解耦。使類和成員的可訪問性最小化無疑是有效的途徑之一。
類似於微服務,
06、使可變性最小化
盡量使類不可變,不可變的類比可變的類更加易於設計、實現和使用,而且更不容易出錯,更安全。
常用的手段:
不提供任何可以修改對象狀態的方法;
使所有的域都是final的。
使所有的域都是私有的。
使用寫時復制機制。並發編程中已講。
07、復合優先於繼承
繼承容易破壞封裝性,而且會使子類的實現依賴於父類。
復合則是在類中增加一個私有域,引用類的一個實例,這樣的話就避免了依賴類的具體實現。
只有在子類確實是父類的一個子類型時,才比較適合用繼承。
繼承需要開發者對父類的結構有一定了解。
實際使用,如果肯定是父類的子類,使用繼承,如果不很肯定,使用復合。
08、接口優於抽象類
接口只有方法申明,抽象類可以寫方法的實現。
java是個單繼承的(不能繼承多個抽象類),但是類允許實現多個接口。
所以當發生業務變化時,新增接口,實現接口只需要新曾接口即可。但是抽象類有可能導致不需要變化的類也不得不實現新增的業務方法。
JDK源碼中常用的一種設計方法:定義一個接口,聲明一個抽象的骨架類實現接口,骨架類類實現通用的方法,而實際的業務類可以同時實現接口又繼承骨架類,也可以只實現接口。
如HashSet實現了implements Set接口 但是又extends 類AbstractSet,而AbstractSet本身也實現了Set接口。其他如Map,List都是這樣的設計的。
方法
09、可變參數要謹慎使用
可變參數是允許傳0個參數的
如果是參數個數在1~多個之間的時候,要做單獨的業務控制。
具體代碼不優雅。
10、返回零長度的數組或集合,不要返回null
方法的結果返回null,會導致調用方的要單獨處理為null的情況。返回零長度,調用方可以統一處理,如使用foreach即可。
JDK中也為我們提供了Collections.EMPTY_LIST這樣的零長度集合
11、優先使用標准的異常
要盡量追求代碼的重用,同時減少類加載的數目,提高類裝載的性能。
常用的異常:
IllegalArgumentException -- 調用者傳遞的參數不合適
IllegalStateException -- 接收的對象狀態不對,
NullPointerException
UnsupportedOperationException –不支持的操作
通用程序設計
12、用枚舉代替int常量
聲明的一個枚舉本質就是一個類,每個具體的枚舉值就是這個枚舉類的實例。
- 使用常量容易在寫代碼時寫錯
- 使用常量如果要使用描述時比較麻煩
- 其他類使用常量時,類編譯時會把常量值直接寫到字節碼中,如果常量值有變化,所有相關的類需要重新編譯,否則會不可預料的錯誤
枚舉高級:
枚舉和行為綁定
所謂枚舉的本質就是一個類,而枚舉中定義的每一個具體的枚舉類型其實就是這個枚舉類的一個實例。
策略枚舉:
13、將局部變量的作用域最小化
1、 在第一次使用的地方進行聲明
2、 局部變量都是要自行初始化,初始化條件不滿足,就不要聲明
最小化的好處,減小局部變量表的大小,提高性能;同時避免局部變量過早聲明導致不正確的使用。
14、精確計算,避免使用float和double
float和double在JVM存儲的時候,有部分要做整數位,有部分要做小數位,所以存在精度上的問題
可以使用int或者long以及BigDecimal
15、當心字符串連接的性能
參考代碼com.jvm.ch07.p15.Test。
在存在大量字符串拼接或者大型字符串拼接的時候,盡量使用StringBuilder和StringBuffer