软件构造学习笔记-第四周
本周重點介紹了mutable和immutable的概念,有些抽象。對于immutable的數(shù)據(jù)類型來說,想修改其引用指向的值,必須使其指向新的內(nèi)存區(qū)域,而不能在原有的內(nèi)存區(qū)域做修改。mutable數(shù)據(jù)類型相反,可以在原來指向的內(nèi)存區(qū)域進(jìn)行修改。設(shè)計ADT時,盡量將小的數(shù)據(jù)型的ADT設(shè)置為immutable,提高程序健壯性。
靜態(tài)/動態(tài)類型檢查
1.數(shù)據(jù)類型:基本數(shù)據(jù)類型和對象數(shù)據(jù)類型的對比。
2.對象類型具有層次結(jié)構(gòu),除了Object類之外的所有類都有父類。Object是所有類的父類。Java中只支持單繼承。
3.靜態(tài)檢查:在不運行程序的前提下的檢測。Java是一種靜態(tài)類型語言,所有變量的種類在編譯階段已經(jīng)明確。在Eclipse中,靜態(tài)檢測在寫代碼的時候就已經(jīng)進(jìn)行,在不合法的位置會用標(biāo)記指明。靜態(tài)類型檢查可以在編譯階段發(fā)現(xiàn)錯誤,避免將錯誤帶入運行階段,可以提高程序的正確性和健壯性。
靜態(tài)檢查可以發(fā)現(xiàn)的錯誤:語法錯誤、函數(shù)名/類名錯誤、參數(shù)數(shù)目錯誤、參數(shù)類型錯誤、返回值類型錯誤等。
4.動態(tài)檢查:像Python一類的動態(tài)類型語言,在程序運行階段才進(jìn)行類型檢查。動態(tài)類型檢查>>靜態(tài)類型檢查>>無檢查,因為動態(tài)類型檢查可以針對具體的值進(jìn)行檢查(比如除數(shù)為0的問題)。靜態(tài)檢查是關(guān)于“類型”的檢查,不考慮值;動態(tài)類型檢查是關(guān)于“值”的檢查。
動態(tài)檢查可以發(fā)現(xiàn)的錯誤:非法參數(shù)值、非法返回值、越界、使用空指針等。
可變/不可變數(shù)據(jù)類型
1.改變一個變量:將該變量指向另一個值的存儲空間。
改變一個變量的值:將該變量當(dāng)前指向的值的存儲空間中寫入一個新的值。
2.final限定變量的指向是不可改變的。如果編譯器不能確定final變量不會改變,就會提示錯誤,也是靜態(tài)類型檢查的一部分。
final類無法派生子類;final變量無法改變值和引用;final方法無法被子類重寫。
3.不變對象:一旦被創(chuàng)建,始終指向同一個值/引用。
可變對象:擁有方法可以修改自身的值/引用。
String類是不可變類的一種。如果要改變一個String對象,則需要將引用修改后的存儲空間。
StringBuilder是一種可變類。如果改變一個StringBuilder對象,則對原本存儲區(qū)域的內(nèi)容修改即可。
4.當(dāng)一個值只有一個引用時,可變與不可變沒有區(qū)別。當(dāng)有多個引用時會有很大區(qū)別。
5.使用不可變類型時,對其頻繁的修改會產(chǎn)生大量的臨時拷貝(需要被回收);可變類型最小化拷貝,提高了效率。不可變類型使用時更加安全,在其它質(zhì)量指標(biāo)上的表現(xiàn)更好。使用時需要權(quán)衡折中。
6.可以通過防御式拷貝(比如返回一個新的對象)來修正可變類型造成的bug。但是大部分時候拷貝不會被客戶端修改,會造成大量的內(nèi)存浪費。如果使用不可變類型,就節(jié)省了頻繁復(fù)制的代價,不可變可以比可變的效率更高,因為不可變從不做防御式拷貝。
7.將可變轉(zhuǎn)換成不可變:
使用傳入的引用->利用傳入引用建立新的對象再使用(在方法中使用復(fù)制對象)
返回引用->返回新的對象(即返回一份復(fù)制)
Snapshot
1.屬于三維視圖的Run-time、Moment、Code層面,用于描述程序運行時的內(nèi)部狀態(tài)。便于交流和理解設(shè)計思路。
2.基本類型的值和對象類型的值在SnapshotDiagram中的表示
對象存儲在堆中,用橢圓形狀標(biāo)明。基本數(shù)據(jù)類型和對象的引用存儲在棧中。基本數(shù)據(jù)類型的標(biāo)識符不會存放在棧中。
對于不可變對象,用雙線橢圓。
String s = “a”;
s = s + “b”;
3.final限定引用(!!!)不可改變。引用不可變,但是引用指向的存儲區(qū)域的值是可以改變的。對于不可變引用,用雙線。可變的引用,也可以指向不可變的值。
例如:新建一個final的List稱為a,可以使用add向a中添加值,但是不能讓a指向另一個List。
可變類型 List Set Map
參考https://www.cnblogs.com/jxxblogs/p/11561629.html
1.List
大小可變(數(shù)組不可變)。
可以通過位置存儲、訪問數(shù)據(jù)。
List是接口,且成員必須是對象。
2.Set
Set是零或多個對象組成的無序集合,不允許元素重復(fù)。
Set是接口,成員是對象。
3.Map
和Python中的Dictionary類似,是由二元組(key-value)構(gòu)成的。
不允許key值重復(fù)。
Map是接口。
迭代器 Iteration
1.主要用途是對集合進(jìn)行遍歷。iteraror有兩個方法:next()返回集合中的下個元素,hasNext()測試迭代器是否達(dá)到集合末尾元素。
2.如果要遍歷集合并刪除指定元素的話,必須使用迭代器。
錯誤示范:
正確示范:
不可變類型
1.基本類型及其封裝對象類型都是不可變的。
2.使用Collections.unmodifiableList、Collections.unmodifiableSet、Collections.unmodifiableMap方法將List、Set、Map包裝成不可變類型。但是這種不可變是在運行階段獲得的,在編譯階段無法據(jù)此進(jìn)行靜態(tài)檢查。即如果在編譯階段嘗試修改包裝類屬性,編譯器不會報錯。
有關(guān)規(guī)約書寫
1.規(guī)約是程序和客戶端之間達(dá)成的一致。只講“能做什么”,不講“怎么實現(xiàn)”。規(guī)約不只是注釋,還包括返回值、參數(shù)、方法名。
2.規(guī)約不包括方法具體實現(xiàn)的內(nèi)容。規(guī)約中的方法都是public方法。代碼中蘊(yùn)含的設(shè)計決策針對編譯器,而規(guī)約(注釋)的設(shè)計決策針對讀者。
3.行為等價性從用戶視角出發(fā),根據(jù)規(guī)約判斷行為是否等價。如果兩個函數(shù)符合同一規(guī)約,則它們等價。
4.前置條件:對客戶端的約束,即在使用方法時必須滿足的條件。
后置條件:對開發(fā)者的約束,方法結(jié)束時必須滿足的條件。
如果前置條件滿足,后置條件必須滿足。前置條件不滿足,方法可做任何事。
5.用@param規(guī)范化前置條件,用@return和@throws規(guī)范后置條件。
6.如果改變了輸入數(shù)據(jù)(mutating methods),要在規(guī)約中明確指出。除非規(guī)約要求,否則不應(yīng)修改輸入?yún)?shù)。
總結(jié)
以上是生活随笔為你收集整理的软件构造学习笔记-第四周的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 谈谈扫码支付的实现流程
- 下一篇: 软件构造学习笔记-第五周