【问题标题】:Persisting the state of an object that has many boolean attributes保持具有许多布尔属性的对象的状态
【发布时间】:2014-09-19 01:28:16
【问题描述】:

对于简单的对象,通常很容易拥有一个“状态”属性,它是一个字符串并且可以存储在数据库中。例如,想象一个 User 类。它可能处于非活动、未验证和活动状态。 可以使用两个布尔值进行跟踪 - “活动”和“已验证” - 但它也可以使用简单的状态机从非活动转换为未验证到活动,同时将当前状态存储在该“状态”中“ 属性。很常见吧?

但是,现在想象一个具有更多布尔属性的类,更重要的是,可以有许多这些属性的组合。例如,可能损坏、丢失、停用、过时等的事物。现在,在单个“状态”属性中跟踪状态变得更加困难。我猜,这是一个非确定性有限自动机或状态机。我真的不想存储“inactive_broken”和“active_missing_outdated”等状态。

我想出的最好办法是同时拥有“状态”属性并存储某种超状态——“可用”与“不可用”,在这种情况下——布尔值。这样我可以在过渡时使用类似守卫的方法。

有没有其他人遇到过这个问题并想出一个好的解决方案来跟踪状态?

【问题讨论】:

    标签: state state-machine


    【解决方案1】:

    您是否考虑过将“状态”序列化为位掩码并将其存储在数据库的整数列中?假设一个实体可以是活动的或非活动的、可用的或不可用的、工作的或损坏的,可以任意组合。

    您可以将每个状态存储为位;打开或关闭。这样一来,值 111 将处于活动状态、可用且正常工作,而值 000 将处于非活动状态、不可用且损坏。

    然后,您可以使用适当的位掩码查询特定组合,或将实体反序列化为具有布尔值的类,以便跟踪您要跟踪的每个状态。向对象添加状态也相对便宜,并且不会破坏已经序列化的对象。

    【讨论】:

      【解决方案2】:

      与上面的答案相同,但比理论更实用:

      • 确定布尔属性的可能数量。所有这些属性的状态可以用 1=true 或 0=false 来表示

      • 采用适当大小的数字数据类型。 unsigned short=16, unsigned int=32, unsigned long=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 个字节。

      • 轻松保存和读取,您只需读取一个 short、int 或 long,这只是一个简单的变量

      • 比较一组属性很容易,因为您只需将一个 short、int 或 long 的数值与另一个进行比较。例如if(Obj.attributes == Obj2.attributes){ }

      【讨论】:

        【解决方案3】:

        我认为您正在描述Orthogonal Regions 的示例。从该链接中,“正交区域解决了当系统的行为被分割成独立的、同时活动的部分时状态数量组合增加的常见问题。”

        实现这一点的一种方法是通过对象组合。例如,您的超级对象包含多个子对象。子对象各自独立地保持其关联状态。超级对象的状态是其所有子对象状态的组合。

        搜索“正交状态”、“正交区域”或“正交分量”以获得更多想法。

        【讨论】:

          猜你喜欢
          • 2011-08-09
          • 2018-11-22
          • 1970-01-01
          • 2021-07-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多