learn from collection framework design
阿新 • • 發佈:2020-05-10
最難忍受的痛苦,也許是想幹一件事情而又不去幹。——羅曼·羅蘭
## 前言
本篇文章算是拾人牙慧吧,偶爾谷歌到一個能很好把collection framework design講好的文件,一是為了總結提升,也是collection framework 的開篇,從設計入手,更透徹的理解這個framework的過去和現在。
參照文件是 美國卡內基梅隆大學的Principles of Software Construction這門課程中一節課的課件 - [collections design.pdf](https://www.cs.cmu.edu/~charlie/courses/17-214/2020-spring/slides/20200228-collections%20design.pdf),建議在看本篇文章前,靜下心來通讀一遍這個文件。
結合自己的理解對collection framework做一個總結。
## 設計目標
- 小且簡單。
- 易擴充套件。
- 與之前存在的集合相容(事實上也做到了,`Vector`和`Hashtable`分別實現了`List`和`Map`介面)。
- 很強的相似性(這個是從易用性角度來考慮的,因為在學習東西的時候,相似的東西是不需要從頭學起的,學習成本自然降低了很多,後續原始碼分析先縱向深入,再橫向類比)。
## API設計準則
- 通用性,避免使用固定集合元素(事實上使用泛型來實現)。
- 與舊API的相容性(`Vector`和`Hashtable`都分別做了重構)。
## 文件的重要性
越是基礎性的框架,設計文件、API或者是使用性文件越是要通俗易懂,這樣基礎性框架才便於開發者使用。畢竟大家都不喜歡用黑盒子,至少不會使用自己不瞭解的東西。
特別注意五種文件的完備性:
- 設計文件
- 概覽文件
- API文件 - 不僅僅是javadoc
- 使用教程文件
- jira list
## 使用者的意見
多去聽取使用者的意見,不好理解不好用的東西,理解不了,用起來自然不爽。
上面說到框架設計應該注意的事項,下面來具體聊一下collection framework design。
## 框架概覽
簡言之,我理解有四部分組成:
1. 層次分明的介面和抽象類。
2. 介面和抽象類的通用實現或完全實現。
3. 基礎演算法。
4. 併發支援(預設是不支援併發的,後來添加了對集合的封裝,但只是簡單的包裝,效率不高,尤其是隨著併發技術的發展,併發粒度越來越小,提供了很多juc的集合實現,逐漸廢棄了集合框架中的原來的併發集合)。
> 值得一提的是,運算元組的工具類跟集合框架同時新增到Java平臺,是集合框架的一個依賴工具。
## API實現
集合介面分為兩組型別介面,分別為 `java.util.Collection`和 `java.util.Map`,Map介面的子類嚴格來說而不是真實的集合。但是,這些介面包含集合檢視操作,使它們可以作為集合進行操作。
隨著這麼多年的積累迭代,collection framework經過十多年的迭代更新(不是截止到現在,而是java 8 ,2014年),最終介面如下。
### Collection 的子介面
Collection 的子介面有:
- `java.util.Set`
- `java.util.SortedSet`
- `java.util.NavigableSet`
- `java.util.Queue`
- `java.util.concurrent.BlockingQueue`
- `java.util.concurrent.TransferQueue`
- `java.util.Deque`
- `java.util.concurrent.BlockingDeque`
### Map的子介面
Map的子介面有:
- `java.util.SortedMap`
- `java.util.NavigableMap`
- `java.util.concurrent.ConcurrentMap`
- `java.util.concurrent.ConcurrentNavigableMap`
### 對併發的支援
如上,支援併發的介面都定義在 `java.util.concurrent`包下,如下:
- `java.util.concurrent.BlockingQueue`
- `java.util.concurrent.TransferQueue`
- `java.util.concurrent.BlockingDeque`
- `java.util.concurrent.ConcurrentMap`
- `java.util.concurrent.ConcurrentNavigableMap`
## 集合和演算法效率問題
通用集合實現的效率問題,在後續原始碼分析過程中會使用大O標記法來討論框架插入刪除或查詢等演算法的複雜度。
## 總結
- 一個好的框架設計,不僅要符合API的設計原則,也要考慮易用性,相容性。
- 多聽取使用者的意見
- 不管是框架的開發者還是使用者,都應該注重文件的使用
最後,我們不是在聊集合的設計嗎,是的,包括集合框架中關鍵的概念,在[collections design.pdf](https://www.cs.cmu.edu/~charlie/courses/17-214/2020-spring/slides/20200228-collections%20design.pdf)中基本上都涉及到了,不做過多的說明,快去看這個文