概述
業務開發中,一個對象經常有多個狀態位,一個狀態位表示一種狀態,比如電商中的商品在618一天,既參加了滿減活動A,又參加了7折活動B,是否參加活動A與是否參加活動B都是該商品的相互獨立的兩個狀態位.一種最簡單的開發就是,用兩個字段分別存儲A與B的狀態位,但是參加活動很多時,無疑是十分不可取.這個時候就需要考慮用一個字段表示多個狀態位,也就是狀態位複用(專業術語不知道叫啥).
上述舉例中,一種狀態位只有兩個值(可以稱之爲boolean 狀態位)0與1,看見0與1就有中很熟悉的感覺,就是計算機的機器語言.
業務中狀態值通常用int表示,一個int 佔4個字節,32位,狀態位可以從2^0-2^(32-1),足以應付一般的業務需求.
demo
package status;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class MarkStatus {
private Integer status = 0;
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
/**
* 判斷是否擁有此標示位的權限
*
* @param markStatus
* @return
*/
public static boolean isMarkPrivilege(Integer markBit, Integer status) {
if (status == null || status == 0 || status == null || status <= 0) {
return false;
}
int power = 1 << (markBit - 1);
if ((status & power) != 0) {
return true;
} else {
return false;
}
}
/**
* 添加某個標示位的權限
*
* @param markBit
*/
public void addMarkPrivilege(Integer markBit) {
if (markBit == null || markBit <= 0) {
return;
}
if (this.status == null) {
this.status = 0;
}
int power = 1 << (markBit - 1);
this.status = this.status | power;
}
/**
* 刪除某個標示位的權限
*
* @param markBit
*/
public void deleteMarkPrivilege(Integer markBit) {
if (markBit == null || markBit <= 0) {
return;
}
if (this.status == null) {
this.status = 0;
}
int power = 1 << (markBit - 1);
this.status = this.status & (~power);
}
public static void main(String[] args) {
/*測試三種狀態,組合的情況有8種,也就是status 可以表示8種狀態(0 比較特殊表示不擁有一種狀態位)*/
int markBitA = 1;
int markBitB = 2;
int markBitC = 3;
/*測試0-20,分別滿足標識位的列表*/
List<Integer> lista = new ArrayList<>();
List<Integer> listb = new ArrayList<>();
List<Integer> listc = new ArrayList<>();
for (int i = 0; i < 20; i++) {
if (MarkStatus.isMarkPrivilege(markBitA, i)){
lista.add(i);
}
if (MarkStatus.isMarkPrivilege(markBitB, i)){
listb.add(i);
}
if (MarkStatus.isMarkPrivilege(markBitC, i)){
listc.add(i);
}
}
System.out.println("A : " + Arrays.toString(lista.toArray()));
System.out.println("B : " + Arrays.toString(listb.toArray()));
System.out.println("C : " + Arrays.toString(listc.toArray()));
/* 打印
* A : [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
B : [2, 3, 6, 7, 10, 11, 14, 15, 18, 19]
C : [4, 5, 6, 7, 12, 13, 14, 15]*/
/*測試*/
MarkStatus s = new MarkStatus();
s.addMarkPrivilege(markBitA);
System.out.println(s.getStatus());//1 在A列表中
s.addMarkPrivilege(markBitB);
System.out.println(s.getStatus());//3在A,B列表中
s.addMarkPrivilege(markBitC);
System.out.println(s.getStatus());//7在A,B,C列表中
}
}