Android中存在着各种各样的Flag的使用,这篇文章主要研究一下这种Flag的运用方式。
为什么要用Flag
程序开发中,不同的场景可能需要不同的控制流;不同的控制流中,后置的控制流可能依赖于前置控制流的某一个属性或状态,这个时候,我们可以考虑引入标志位Flag,记录前置控制流中的属性或状态,在后置控制流执行时再去访问。在相对简单的场景中,我们完全可以这么处理:
boolean success = false;
public void putElephantIntoFridge(){
//step 1
openTheDoor();
//step 2
putElephant();
//step3
closeTheDoor();
}
private void closeTheDoor() {
if (success) {
lockTheDoor();
} else {
runAway();
}
}
private void putElephant() {
Log.i(TAG, "putElephant: ");
Random random = new Random();
success = random.nextInt(2) == 1;
}
private void openTheDoor() {
Log.i(TAG, "openTheDoor: ");
}
private void lockTheDoor() {
Log.i(TAG, "lockTheDoor: ");
}
private void runAway(){
Log.i(TAG, "runAway: ");
}
像上面这种比较简单的控制流,我们可以直接考虑加一个标志位flag,来确定后续控制流的执行逻辑。 但是,如果控制流程中会有多个case影响到后续的执行分支,或者这些case对应的flag需要传递给其他的函数或方法,一昧地添加新的flag,要么会让整个函数控制流变得无比混乱,要么就会徒增大量的离散flag,导致关联的控制流需要新增多个flag输入参数。
这种情况下,我们可以考虑将flag聚拢在一起,通过状态集StateSet或者位运算Bit Operation来消除离散的flag信息,我们现在主要来探讨一下使用位运算来聚合flag的方案。
位运算与Flag
开始之前,先简单复习一下位运算的几个运算符:
操作符符 | 运算 | 使用 | 结果 | 例子 |
---|---|---|---|---|
& |
按位与 | exp1 & exp2 |
按位比较exp1和exp2的data,如果都为1,结果为1,否则结果为0 | 1100&1010 = 1000 |
| |
按位或 | exp1 | exp2 |
按位比较exp1和exp2的data,如果有一个为1,结果为1;否则结果为0 | 1100 | 1010 = 1110 |
^ |
按位异或 | exp1 ^ exp2 |
按位比较exp1和exp2的data,如果取值不同,结果为1;否则结果为0 |