2012-04-05 43 views
0

對於簡單對象,通常很容易擁有「狀態」屬性,該屬性是字符串並可存儲在數據庫中。例如,設想一個用戶類。它可能處於不活躍,未經驗證和積極的狀態。這個可能被跟蹤兩個布爾值 - 「活動」和「驗證」 - 但它也可以使用一個簡單的狀態機從非活動狀態轉換爲未驗證活動狀態,同時將當前狀態存儲在該「狀態」屬性中。很常見,對嗎?堅持具有許多布爾屬性的對象的狀態

但是,現在想象一個具有更多布爾屬性的類,更重要的是,它們可以有很多組合。例如,可能被破壞,丟失,停用,過時等的事情。現在,在單個「狀態」屬性中跟蹤狀態變得更加困難。我猜這是一個非確定性有限自動機或狀態機。我真的不想存儲諸如「inactive_broken」和「active_missing_outdated」等狀態,等等。

我所想到的最好的結果是同時具有「狀態」屬性和存儲某種超狀態 - 「可用「vs」不可用「,在這種情況下 - 每個布爾值。這樣,我可以在轉換時擁有類似警衛的方法。

有沒有其他人遇到這個問題,想出一個很好的解決方案來跟蹤狀態?

回答

1

您是否考慮將「狀態」序列化爲位掩碼並將其存儲在數據庫的整數列中?假設一個實體可以處於活動狀態或非活動狀態,可用或不可用,或以任何組合方式工作或中斷。

你可以將每個狀態存儲一下;無論是關閉還是關閉。這樣111的值將是活動的,可用的和工作的,而值000將是無效的,不可用的和破碎的。

然後,您可以使用適當的位掩碼來查詢特定的組合,或者將實體反序列化爲具有您想要跟蹤的每個狀態的布爾值的類。將狀態添加到對象也不會相對便宜,並且不會打破已經序列化的對象。

1

與上述相同的答案,但比理論更實用:

  • 確定布爾的儘可能多的屬性。所有這些屬性的狀態可以用1 = true或0 = false表示

  • 取適當大小的數字數據類型。無符號短= 16,無符號整型= 32,無符號長= 64,如果有一個更大的類型採取的數值的數組:例如用於128點的屬性取

    unsigned long[] attr= new long[2]; // two long side by side 
    
  • 每個比特可以用下面的代碼來訪問

    bool GetBitAt(long attr, int position){ 
        return (attr & (1<<(position-1)) >0; 
    } 
    long SetBitAt(long attr, int position, bool value){ 
        return attr|=1<<(position-1); 
    } 
    
  • 現在有每個位的位置表示的屬性。例如:位5意味着是否可用?

    bool IsAvailable(long attr){ 
         return GetBitAt(attr, 5); 
    } 
    

  • 例如節省空間64個屬性只需要8個字節。

  • 易於保存和讀取你只需要讀一段,int或長,這僅僅是一個簡單的變量

  • 比較一組屬性是很容易,你將簡單的比較短,int或長「與另一個數字值。例如如果(Obj.attributes == Obj2.attributes){}

0

我想您所描述的Orthogonal Regions一個例子。從這個環節,「正交區解決了當系統的行爲被分割爲獨立的,同時活動的部分時,組合式增加狀態的頻繁問題。」

您可能會實現這一目標的一種方法是通過對象組合。例如,你的超級對象包含幾個子對象。這些子對象各自獨立於彼此維護其相關狀態。超級對象的狀態是其所有子對象狀態的組合。

尋找「正交態」,「正交區」或「正交分量」以獲得更多想法。