內部狀 態的改變意味著它很可能違反了對象的不變性,至少是臨時的。當你改變了City 這個字段後,你就使a1處於無效狀態。城市的改變使得它與洲字段及以區碼字段 不再匹配。代碼的有害性看上去還不足以致命,但這對於多線程程序來說只是一 小部份。在城市變化以後,洲變化以前的任何內容轉變,都會潛在的使另一個線 程看到一份矛盾的數據視圖。
Okay,所以你不准備去寫多線程程序。你 仍然處於困境當中。想象這樣的問題,區代碼是無效的,並且設置拋出了一個異 常。你只是完成了一些你想做的事,可你卻使系統處於一個無效的狀態當中。為 了修正這個問題,你須要在地址類裡面添加一個相當大的內部驗證碼。這個驗證 碼應該須要相當大的空間,並且很復雜。為了完全實現期望的安全性,當你修改 多個字段時,你須要在你的代碼塊周圍創建一個被動的數據COPY。線程安全性可 能要求添加一個明確的線程同步用於檢測每一個屬性訪問器,包括set和get。總 而言之,這將是一個意義重大的行動--並且這很可能在你添加新功能時被過分的 擴展。
取而代之,把address結構做為一個恆定類型。開始把所有的字段 都改成只讀的吧:
public struct Address
{
private readonly string _line1;
private readonly string _line2;
private readonly string _city;
private readonly string _state;
private readonly int _zipCode;
// remaining details elided
}
你還要移除所有的屬性設置 功能:
public struct Address
{
// ...
public string Line1
{
get { return _line1; }
}
public string Line2
{
get { return _line2; }
}
public string City
{
get { return _city; }
}
public string State
{
get { return _state; }
}
public int ZipCode
{
get { return _zipCode; }
}
}