對象導論之容器(一)

容器(一)
  通常說來,如果不知道在解決某個特定問題時需要多少個對象,或者它們將存活多久,那麼就不可能知道如何存儲這些對象。如何才能知道需要多少空間來創建這些對象呢?答案是你不可能知道,因爲這類信息只有運行時才能獲得。
  對於面向對象設計中的大多數問題而言,這個問題的解決法案似乎過於輕率:創建另一種對象類型。這種新的對象類型持有對其他對象的引用。當然,你可以用在大多數語言中都有的數字類型來實現相同的功能。但是這個通常被稱爲容器(也稱爲集合,不過Java類庫以不同的含義使用“集合”這個術語,所以將使用“容器”這個詞)的新對象,在任何需要時都可擴充自己以容納你置於其中的所有東西。因此不需要知道將來會把多少個對象置於容器中,只需要創建一個容器對象,然後讓它處理所有細節。
  幸運的是,好的OOP語言都有一組容器,它們作爲開發包的一部分。在C++中,容器是標準C++類庫的一部分,經常被稱爲標準模板類庫(Standard Template Library,STL)。Object Pascal在其可視化構建庫(Visual Component Library,VCL)中有容器;Smalltalk提供了一個非常完備的容器集;Java在其標準類庫中包含有大量的容器。在某些類庫中,一兩個通用容器足夠滿足所有的需要;但是在其他類庫(例如Java)中,具有滿足不同需要的各種類型的容器,例如List(由於存儲序列),Map(也被稱爲關聯數組,用來建立對象之間的關聯),Set(每種對象類型只持有一個),以及諸如隊列、樹、堆棧等更多的構件。
  從設計的觀點來看,真正需要的只是一個可以被操作,從而解決問題的序列。如果單一類型的容器可以滿足所有需要,那麼就沒有理由設計不同種類的序列了。然而還是需要對容器有所選擇,這有兩個原因。第一,不同容器提供了不同類型的接口和外部行爲。堆棧相比於隊列就具備不同的接口和行爲,也不同於集合和列表的接口和行爲。它們之中的某種容器提供的解決方案可能比其他容器要靈活得多。第二,不同的容器對於某些操作具有不同的效率。最好的例子就是兩種List的比較:ArrayList和LinkedList。它們都是具有相同接口和外部行爲的簡單的序列,但是它們對某些操作所花費的代價卻有天壤之別。在ArrayList中,隨機訪問元素是一個花費固定時間的操作;但是,對LinkedList來說,隨機選取元素需要在列表中移動,這種代價是高昂的,訪問越靠近表尾的元素,花費的時間越長。而另一方面,如果想在序列中間插入一個元素,LinkedList的開銷卻比ArrayList要小。上述操作以及其他操作的效率,依序列底層結構的不同而存在很大的差異。我們可以在一開始使用LinkedList構建程序,而在優化系統性能時改用ArrayList。接口List所帶來的抽象,把在容器之間進行轉換時對代碼產生的影響降到最小程度。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章