天天看點

資料、事實、實體、值對象、事務、不變性

資料有兩個重要屬性:首先資料是基于時間的,資料是表達一段時間内一個邏輯為真的事實。另外一個屬性是資料本質上是不可變的,因為和時間有關,我們是不能回到過去改變資料的真實性。這兩個屬性就意味着:對資料你其實隻有兩個主要的操作:讀取現有資料,并(随着時間)添加更多新的資料,crud(增删改查)稱為cr(增讀)。這樣,crud其實沒有u修改,因為修改對不可變資料是不其作用的(非常類似ddd中值對象不可變,不能修改,隻能更換)。crud中也沒有删除delete,其實大部分删除其實是一種建立新資料,如果bob停止跟随mary,但是他們不能改變他曾經跟随過他的事實,删除那個他不跟随她的資料,你會增加一個資料記錄,說他在某個時刻不再跟随她了。

其實狀态變化有兩種思維:一種是過程形式,一種是邏輯形式。

過去我們的實體都是列出對其認識的内在屬性,當事件發生緻使實體發生變化時,往往就是加鎖後逐一改變,或者事務方式(類似副本方式)。“逐一改變”就是過程式,具體詳細地描述變化過程,于是在并行的時候缺失原子性,為了實作避免髒讀等問題,加鎖成了一種手段。當然,事務方式也解決了這樣的問題,這與非副本的不變值對象方式,是達到同樣目的的不同方式,同時這兩者都屬于邏輯表達。以前我作過比較,在領域當中談論邏輯變化,我認為後者較好。

值對象是實體狀态的一種落實,我過去提出過的觀點,這是源自于狀态變化的邏輯形式思維。談論邏輯時,狀态遷移必須具有原子性,是以我在某個文章說值對象不變性,可以達到去鎖的目的。

注意:值對象不變性源自值,并非因為實體狀态,是因為值對象具有值的不變性,是以才能成為實體狀态的落實。

一些更深入的認識:

存在狀态變化即存在副作用(side effect),是以實體是副作用存在的因。很多人認為副作用是壞的,應該去掉,但這隻限于邏輯運算時。隻要人們想獲得資訊,副作用就根本不能避免,最容易了解就是print。

可變的實體與不可變的狀态,正好就是副作用存在的分界線。實體之是以會存在,其實是因為人們想擷取資訊,于是值對象(值)載體便出現了——引用對象(即實體對象)。

狀态遷移,就是實體發生變化,它說明實體從一個狀态遷移到另一個狀态。這裡面最小單元是狀态,也就是說我們考慮的不是狀态的構成及其内在變化(逐一改變),而是計算出新狀态,然後以“替換”的手段來實作實體變化。這與我們所說到的值對象不變性和事實是最小單元如出一轍。(是以“狀态遷移”是一種事實觀)

狀态是表達一段時間内一個邏輯為真的事實,這句話很好說明了事實觀與實體觀的聯系。

過去我思考“什麼是實體”,其實實體很簡單,就是一個key,是為了差別與其他存在的存在。而我們寫類的時候,其中的id并非實體key,而“類名+類id”才是實體key。是以關系資料庫中表方式與類方式類似,并不完全滿足事實觀,而key-value資料庫能更好展現邏輯。關系資料庫的資料平鋪方式,使得查詢速度極快,同時實作了邏輯查詢,但這并非從實作“産生事實的邏輯”角度出發的——事件的角度。

immutable is eveything,不可變是一切。

狀态變化是由事件引起的,從事件來劃分。

the immutability exists not for the sake of itself. immutability is abstraction. it does not "exist" in nature. world is mutable, world is permanently changing.....

一、

其實這就是一種“連續”和“離散”思維的差別,盡管世界在我們感官中是連續的,但連續過程和中間的“切面狀态”不是我們關注的,業務說的是規則,是邏輯的,正如我們經常說的“業務邏輯”。在規則或者邏輯中,不存在所謂的切面狀态。例如“借書”這一個原子動作,有人會“借一半”,或者說“借一半”是我們所關注的狀态?

二、

若果我們一個個地改屬性,當改了第一個屬性值,沒改第二個屬性值時,這就存在了所謂的切面狀态。單線程時,因為順序執行,不會讀出切面狀态,變相成為原子操作,但多線程并發時,讀出無效的切面狀态是可能的。解決的方式:

1)改的時候不能讀,就是我們以前用得最多的鎖;

2)随時可讀,改的時候必須“同一時間”完全改完,而這就是不變性的整體替換;

3)當然後來又想到一種,讀與改不會同時進行,暫時感覺比較複雜,沒有深入,淺思考了下,感覺實時相對較弱。

三、

還有一點,事務性和不變性,個人認為兩者很像,但又有點不同:

事務講究複制隔離,達到不互相影響,而且最後也需要替換。

不變性無需複制,因為其一開始就要求在邏輯運算期間是“不能改”。

兩者相似點:

1)并行時都是互相不影響;

2)更新時都是替換手段。

不同點:

1)事務的參與邏輯是在邏輯執行前就複制好,得到隔離性;事務包裝整個過程,實作原子性。

2)不變性方式的“結果對象”是在邏輯執行完後,根據各種條件建立的,其原子性展現在替換,并不是包裝過程。

總的來說就是一前一後,事務有點像“平行世界”的概念。還有有趣的一點是,不變性前後兩個狀态不要求是同構的。不變性還有很多有趣的地方,這裡就不一一列舉了。而不變性也有缺點的,如要多對象同時改變時,需要機制來處理。

為什麼有這樣大統一美妙大道至簡的現象呢?因為計算機軟體系統是本身是符号邏輯或者形式邏輯或分析邏輯的一種展現,而不變性是邏輯上的一個基礎概念(蒯因與引用透明),如果你學習了分析邏輯的這個基礎,你就找對了方向,但是如果你學習幾十年資料結構和算法基礎,你不一定能悟出其背後的邏輯真義。

vo相對的是ro(referenceobject),獨立于“狀态、實體”概念的,或者說是不同層次的。隻是vo和ro出現相對較早,而且比較吻合“狀态、實體”概念。是以,值對象隻是狀态的落實,或者說實作。

“實體狀态在某個時間點上狀态是靜止的”,瞬時的實體狀态映射到計算機就是不變的資料,在對象思維中就是值對象。而實體則是ro,不過注意的是這個引用概念有點變化,并不是引用位址,而是變成實體key。

值對象的不變性是源自于值概念的,試想為啥非要叫做“值對象”,而不叫“不變對象”。