软件构造随笔三
在回看mit閱讀材料13之后,這篇隨筆分享一些我在這篇閱讀材料中的收獲。
還是在開頭感謝李秋豪學長的翻譯版本。
這篇閱讀材料向我們介紹了幾個有關ADT設計的思想和概念,:
不變量(invariants)
表示暴露(representation exposure)
抽象函數(abstraction functions)
表示不變量(representation invariants)
我在之前java編程時確實只會關注一個ADT是否正確完成了功能,不會考慮其他的問題。
這種做法在我們完成一些小程序時沒有問題,但當涉及到大型項目,里面有幾十個,甚至幾百個ADT時,這樣的做法就不再適合了。
1:不變量:
不變量是一種屬性,它在程序運行的時候總是一種狀態,一旦一個不變類型的對象被創建,它總是代表一個不變的值,我們希望這個值在程序運行時始終保持不變。而當不變量被破壞時,我們的程序功能也很有可能會被破壞。
以閱讀材料中的例子來說:
Tweet是個不可變類型,即一旦被創建,author, message, 和 date都不能被改變,但是:
在這樣操作下,author就被改變了,如過允許這樣的改動,之后的代碼就很有可能會錯誤。這樣的操作就會導致表示暴露(Rep exposure)。
2.解決方法:
2.1:首先我們可以這樣處理:
將成員變量變為private 和 final類型,private 表示這個區域只能由同類進行訪問;而final確保了該變量的索引不會被更改,對于不可變的類型來說,就是確保了變量的值不可變。
但這里例子中還有一個問題,Date為可變類型,所以工作還為結束
(在這里插入一些今天習題課的內容:例如:有成員變量Set a,其中Person為可變類型,而某函數會返回a。
為了保證表示不變量,我們首先會想到保護性復制,但由于Person類還是可變的,所以還要使用java中的Collections.unmodifiableList()來處理)
2.2:
當使用如下操作時就會出現錯誤:
錯誤原因如快照圖所示:
這樣的話方法中的改變會導致成員變量的改變,導致錯誤。
解決方法就是要做保護性復制:
這樣不論在方法中改變改變都不會改變原來的成員變量。
2.3:下面是一種不常見的情況,在閱讀材料前確實沒有考慮過這種情況
出錯的原因是,所有的Tweet中的date的執向相同。不過個人感覺這里的問題主要是Date date的處理出了問題,可以在循環中每次新new一個,而不是使用同一個date。當然也可以認為是Tweet類的構造器有漏洞。
在后者的理解下,改進如下:
2.4:
除了上面的方法外,我們在設計時可以直接選用不可變類型如java.time.ZonedDateTime,然后直接加private,final就可以解決,或者我們還能使用Collections.unmodifiableList()來處理,不過缺點是Java不會在編譯的時候對你對“不可變”列表的修改提出警告。
以上就是目前位置我常用的幾種防止表示暴露的方法,以后要再學到新方法,會陸續添加。
以上內容如有錯誤,歡迎指正。
總結
- 上一篇: java 异常处理机制(java 编程思
- 下一篇: 第 52 章 Web Server Op