位状态的使用

349 阅读2分钟

title: 位状态的使用 date: 2017.05.04 02:15 categories:

  • 技术博客 tags:
  • Web
  • Java

Web项目中很常见的一种需求:即用户持有各种不同的状态。

这次使用到的是其中一种,即非开即合的情况,也就是同一状态只能有开和闭两种情况,比如用户有无绑定手机、用户是否实名认证、用户订单是否送达等等。

按照之前的做法,我一般是在用户信息持有类(如User)中不停地加属性。比如isBindPhoneisBindEmail,项目初期还好说,可能也就五六个状态,再往后就是灾难,可能有二十个这种状态,再往后就不敢想了,所以得想个办法来保持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种。点这里回顾你大学就了解的数据类型知识点。
  • 对不同状态的关系管理使用到了与或异或操作。点这里看他的解释
  • 一个缺点,代码用起来可读性较差。