title: 位状态的使用 date: 2017.05.04 02:15 categories:
- 技术博客 tags:
- Web
- Java
Web项目中很常见的一种需求:即用户持有各种不同的状态。
这次使用到的是其中一种,即非开即合的情况,也就是同一状态只能有开和闭两种情况,比如用户有无绑定手机、用户是否实名认证、用户订单是否送达等等。
按照之前的做法,我一般是在用户信息持有类(如User
)中不停地加属性。比如isBindPhone
,isBindEmail
,项目初期还好说,可能也就五六个状态,再往后就是灾难,可能有二十个这种状态,再往后就不敢想了,所以得想个办法来保持User
的简洁可用。
前面已经提到了,这些状态都是非开即合,学过计算机的应该都能感觉到这东西应该用二进制来做,因为二进制不是0就是1,怎么用到这里来代替之前的做法呢?
答案是:位状态。
1.编写工具类
作用是封装所有状态的值以及操作,下面是代码片段。
public class BitStatesUtil { public final static Long BIND_PHONE = 1L << 0; //用户是否绑定了邮箱 public final static Long BIND_EMAIL = 1L << 1; // 用户是否实名认证 /** * @param states * 所有状态值 * @param value * 需要判断状态值 * @return 是否存在 */ public static boolean hasState(long states, long value) { return (states & value) != 0; } /** * @param states * 已有状态值 * @param value * 需要添加状态值 * @return 新的状态值 */ public static long addState(long states, long value) { if (hasState(states, value)) { return states; } return (states | value); } /** * @param states * 已有状态值 * @param value * 需要删除状态值 * @return 新的状态值 */ public static long removeState(long states, long value) { if (!hasState(states, value)) { return states; } return states ^ value; }}复制代码
2.理解上面的设计
- 代码是否合适用过来,主要还是看业务需求。
- 不同状态的表示同样使用了数字,而在二进制下恰好只需要
<<1
来进行占位操作,增加新的状态时只需要在之前的基础上递增一位,示例中给出了两个状态。 - 数据类型的选择取决于自己项目中的需求,多就取大,少就取小,long类型64位已经可以代表64种。
- 对不同状态的关系管理使用到了与或异或操作。。
- 一个缺点,代码用起来可读性较差。