代碼整潔之道-第6章-對象和數據結構-讀書筆記

第 6 章 對象和數據結構

  將變量設置爲私有(private)有一個理由:我們不想其他人依賴這些變量。

6.1 數據抽象

  隱藏實現並非只是在變量之間放上一個函數層那麼簡單。隱藏實現關乎抽象!類並不簡單地用取值器和賦值器將其變量推向外間,而是暴露抽象接口,以便用戶無需瞭解數據的實現就能操作數據本體。
  我們不願暴露數據細節,更願意以抽象形態表述數據,這並不只是用接口和 / 或賦值器、取值器就萬事大吉。要以最好的方式呈現某個對象包含的數據,需要做嚴肅的思考。傻樂着亂加取值器和賦值器,是最壞的選擇。

6.2 數據、對象的反對稱性

  對象把數據隱藏於抽象之後,曝露操作數據的函數。數據結構曝露其數據,沒有提供有意義的函數。他們是對立的。這種差異貌似微小,但卻有深遠的含義。
  過程式代碼(使用數據結構的代碼)便於在不改動既有數據結構的前提下添加新函數。面向對象代碼便於在不改動既有函數的前提下添加新類。反過來講也說得通:過程式代碼難以添加新數據結構,因爲必須修改所有函數。面向對象代碼難以添加新函數,因爲必須修改所有類。所以,對於面向對象較難的事,對於過程式代碼卻較容易,反之亦然。
  在任何一個複雜系統中,都會有需要添加新數據類型而不是新函數的時候。這時,對象和麪向對象就比較合適。另一方面,也會有想要添加新函數而不是數據類型的時候。在這種情況下,過程式代碼和數據結構更合適。

6.3 得墨忒耳律

  著名的得墨忒耳律(The Law of Demeter)認爲,模塊不應瞭解它所操作對象的內部情形。對象隱藏數據,曝露操作。這意味着對象不應通過存取器曝露其內部結構,因爲這樣更像是曝露而非隱藏其內部結構。
  更準確地說,得墨忒耳律認爲,類 C 的方法 f 只應該調用以下對象的方法:

  • C
  • 由 f 創建的對象;
  • 作爲參數傳遞給 f 的對象;
  • 由 C 的實體變量持有的對象。

  方法不應調用由任何函數返回的對象的方法。

6.3.1 火車失事

  對象才涉及得墨忒耳律,數據結構沒有任何行爲,則自然會曝露其內部結構,得墨忒耳律也就不適用了。

6.3.2 混雜

  一半是對象,一半是數據結構這種混合結構擁有執行操作的函數,也有公共變量或公共訪問器及改值器。無論出於怎樣的初衷,公共訪問器及改值器都把私有變量公開化,誘導外部函數以過程式程序使用數據結構的方式使用這些變量。
  此類混雜增加了新函數的難度,也增加了添加新數據結構的難度,兩面不討好。應避免創造這種結構。它們的出現,展現了一種亂七八糟的設計,其作者不確定—或者更糟糕,完全無視—它們是否需要函數或類型的保護。

6.3.3 隱藏結構

  分析獲取對象的內部結構的目的,用方法來代替獲取,防止當前函數因瀏覽它不該知道的對象而違反德墨忒爾律。

6.4 數據傳送對象

  最爲精煉的數據結構,是一個只有公共變量、沒有函數的類。這種數據結構有時被稱爲數據傳送對象,或 DTO(Data Transfer Objects)。 DTO 是非常有用的結構,尤其是在與數據庫通信、或解析套接字傳遞的消息之類場景中。
Active Record
  Active Record 是一種特殊的 DTO 形式。它們是擁有公共(或可豆式訪問的)變量的數據結構,但通常也會擁有類似 save 和 find 這樣的可瀏覽方法。 Active Record 一般是對數據庫表或其他數據源的直接翻譯。
  經常發現開發者往這類數據結構中塞進業務規則方法,把這類數據結構當成對象來用。這是不智的行爲,因爲它導致了數據結構和對象的混雜體。
  當然,解決方案就是把 Active Record 當做數據結構,並創建包含業務規則、隱藏內部數據(可能就是 Active Record 的實體)的獨立對象。

6.5 小結

  對象曝露行爲,隱藏數據。便於添加新對象類型而不誤修改既有行爲,同時也難以在既有對象中添加新行爲。數據結構曝露數據,沒有明顯的行爲。便於向既有數據結構添加新行爲,同時也難以向既有函數添加新數據結構。

6.6 文獻

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