Invariant
Invariant
不變式是在物件整個生命週期都必須為真的業務規則。狀態只能沿流程轉換、某幾個欄位被同一條規則綁住必須一起換、錯誤代碼必須屬於對應分類——這些條件只要有一條被違反、物件就處於業務上不該存在的狀態。不變式的存在是判定型別為領域模型而非資料袋的關鍵依據:有不變式的型別需要領域模型的設計投資,沒有的就是資料袋。
概念位置
不變式跟輸入驗證的責任不同。不變式守「這個物件能不能存在」——違反時物件不該被建出來;輸入驗證守「使用者輸入對不對」——違反時要好好告訴使用者。兩者混放會讓格式驗證塞進建構子、或存在條件放進 validator。不變式跟 snapshot 有交集——歷史 snapshot 凍結的是過去規則下合法的狀態、回讀時不一定通過新規則的不變式。
可觀察訊號
型別上出現「請用某方法修改」「此欄位勿直接改」的註解時,不變式已經到場、強制還停在文件層。建構子或方法的 throw / assert 是不變式在執行層工作的證據;grep 得到零個對應檢查時,是宣稱約束但未強制。
設計責任
同一條不變式可以落在文件層(註解)、型別層(介面簽名)或執行層(建構子檢查),層次決定違反時發生什麼——靜默通過、編譯失敗、當場拒絕。選擇依違反代價與建置成本折算。教學層展開見 不變式的強制層次。