如果一个用户拥有多种类型, 改如何来设计这样一个对象的结构呢?
很容易就想到使用List来保存用户的多种类型, 是否还有其他更简洁高效的方式呢?
使用位运算符,可以巧妙的来达到这种目的。
首先将用户抽象出来。
public abstract class User {
abstract boolean isStudent () ;
abstract boolean isStewardess() ;
abstract boolean isTeacher() ;
abstract boolean iNurse() ;
abstract boolean isPolicewoman() ;
@Override
public String toString() {
StringBuilder sb = new StringBuilder() ;
sb.append("isStudent:").append(isStudent()).append(",")
.append("isStewardess:").append(isStewardess()).append(",")
.append("isTeacher:").append(isTeacher()).append(",")
.append("iNurse:").append(iNurse()).append(",")
.append("isPolicewoman:").append(isPolicewoman());
return sb.toString() ;
}
}
下面给出了三种不同的实现方式。
第一种:就是最容易想到的List 。 也是最简单的。
import java.util.ArrayList;
import java.util.List;
public class UserImplA extends User{
private List<Integer> typesList = new ArrayList<Integer>() ;
static final Integer NURSE = 1 ;
static final Integer POLICEWOMAN = 2 ;
static final Integer STEWARDESS = 3 ;
static final Integer STUDENT = 4 ;
static final Integer TEACHER = 5 ;
public UserImplA(Integer ... types){
if(types != null){
for (Integer i : types) {
typesList.add(i) ;
}
}
}
@Override
public boolean iNurse() {
return typesList.contains(NURSE) ;
}
@Override
public boolean isPolicewoman() {
return typesList.contains(POLICEWOMAN) ;
}
@Override
public boolean isStewardess() {
return typesList.contains(STEWARDESS) ;
}
@Override
public boolean isStudent() {
return typesList.contains(STUDENT) ;
}
@Override
public boolean isTeacher() {
return typesList.contains(TEACHER) ;
}
}
第二种:使用字符串。 每一个类型,定义为一个字符。 如果一个用户拥有多种类型就让多种类型累加
public class UserImplC extends User{
static final String NURSE = "A" ;
static final String POLICEWOMAN = "B" ;
static final String STEWARDESS = "C" ;
static final String STUDENT = "D" ;
static final String TEACHER = "E" ;
private StringBuffer userType = new StringBuffer();
public UserImplC(String... types){
if(types != null){
for (String s : types) {
userType.append(s) ;
}
}
}
@Override
public boolean iNurse() {
return userType.indexOf(NURSE) != -1;
}
@Override
public boolean isPolicewoman() {
return userType.indexOf(POLICEWOMAN) != -1;
}
@Override
public boolean isStewardess() {
return userType.indexOf(STEWARDESS) != -1;
}
@Override
public boolean isStudent() {
return userType.indexOf(STUDENT) != -1;
}
@Override
public boolean isTeacher() {
return userType.indexOf(TEACHER) != -1;
}
}
第三种:就是使用位运算符了。
public class UserImplB extends User{
static final Integer NURSE = 1 ;
static final Integer POLICEWOMAN = 2 ;
static final Integer STEWARDESS = 4 ;
static final Integer STUDENT = 8 ;
static final Integer TEACHER = 16 ;
private int userType = 0 ;
public UserImplB(Integer... types){
if(types != null){
for (Integer i : types) {
userType |= i ;
}
}
}
@Override
public boolean iNurse() {
return (userType & NURSE) == NURSE;
}
@Override
public boolean isPolicewoman() {
return (userType & POLICEWOMAN) == POLICEWOMAN;
}
@Override
public boolean isStewardess() {
return (userType & STEWARDESS) == STEWARDESS;
}
@Override
public boolean isStudent() {
return (userType & STUDENT) == STUDENT;
}
@Override
public boolean isTeacher() {
return (userType & TEACHER) == TEACHER;
}
}
其中的多种类型的值 ,必须是2的倍数 。 这样才能够使用位运算符。
以上面的为例:
NURSE = 1 转换二进制码为: 0000 0001
POLICEWOMAN = 2 转换二进制码为: 0000 0010
STEWARDESS= 4 转换二进制码为: 0000 0100
STUDENT= 8 转换二进制码为: 0000 1000
TEACHER= 16 转换二进制码为: 0001 0000
& 运算符的运算规则是 :“都为1,则为1 ,否则为0”
| 运算符的运算规则是:“有一个为1,则为1,否则为0”
例如: NURSE | POLICEWOMAN
= 0000 0001
0000 0010
结果= 0000 0011 = 3
然后使用结果与制定的TYPE去进行&操作, 就能判断结果中是否包含该TYPE, 如果&操作的值 = 该TYPE , 那么就表示该结果包含TYPE
例如:结果 & NURSE
= 0000 0011
0000 0001
结果= 0000 0001
测试类:
public class Test {
public static void main(String[] args) {
User a = new UserImplA(UserImplA.NURSE , UserImplA.STUDENT) ;
System.out.println("A--------------------------------------------------");
System.out.println(a);
User b = new UserImplB(UserImplB.POLICEWOMAN , UserImplB.STEWARDESS ,UserImplB.TEACHER) ;
System.out.println("\nB--------------------------------------------------");
System.out.println(b);
User c = new UserImplC(UserImplC.STUDENT ,UserImplC.STEWARDESS) ;
System.out.println("\nC--------------------------------------------------");
System.out.println(c);
}
}
输出:
A--------------------------------------------------
isStudent:true,isStewardess:false,isTeacher:false,iNurse:true,isPolicewoman:false
B--------------------------------------------------
isStudent:false,isStewardess:true,isTeacher:true,iNurse:false,isPolicewoman:true
C--------------------------------------------------
isStudent:true,isStewardess:true,isTeacher:false,iNurse:false,isPolicewoman:false