別再 if/else 走天下了
轉載地址:https://mp.weixin.qq.com/s/ufRf8DQQRYQI0q2VxG3hQg
一 初衷
我們在開發中,經常會遇到一個系統,有多種角色構成。業務之間也會產生層級管理,權限劃分等場景。
在使用 if/else 樂此不疲的時候 我們通常會將代碼寫成下面的樣子:
if (roleName.equals("ROLE_ROOT_ADMIN")) {
// 系統管理員有A權限
result = "ROLE_ROOT_ADMIN: " + "has AAA permission";
} else if (roleName.equals("ROLE_ORDER_ADMIN")) {
// 訂單管理員有B權限
result = "ROLE_ORDER_ADMIN: " + "has BBB permission";
} else if (roleName.equals("ROLE_NORMAL")) {
// 普通用戶有C權限
result = "ROLE_NORMAL: " + "has CCC permission";
} else {
result = "XXX";
}
return result;
不僅閱讀起來比較痛苦,而且閱讀起來也痛苦。
二 誰來拯救我
1、switch/case ?
NO NO NO 這哥們跟 if/case 區別不大的
2、使用【枚舉】不香嗎 ?
前段時間 看有片文章 提到枚舉的性能問題,這裏先不說這個,只關注怎麼代替 if/else;
首先定義一個公用接口 RoleOperation,定義不同角色的行爲。
public interface RoleOperation{
String op();// 表示某個角色可以做哪些op操作}
定義一個枚舉類,實現上面的接口,定義具體的動作;
enum RoleEnum implements RoleOperation {
// 系統管理員(有A操作權限)
ROLE_ROOT_ADMIN {
@Override
public String op() {
return "ROLE_ROOT_ADMIN:" + " has AAA permission";
}
},
// 訂單管理員(有B操作權限)
ROLE_ORDER_ADMIN {
@Override
public String op() {
return "ROLE_ORDER_ADMIN:" + " has BBB permission";
}
},
// 普通用戶(有C操作權限)
ROLE_NORMAL {
@Override
public String
op() {
return "ROLE_NORMAL:" + " has CCC permission";
}
};
}
簡單使用
JudgeRole judgeRole = new JudgeRole();
System.out.println(judgeRole.judge("ROLE_ROOT_ADMIN"));
3、【工廠模式】不香嗎
先寫好每個 角色對應的行爲 和 具體動作
// 系統管理員(有A操作權限)
public class RootAdminRole implements RoleOperation {
private String roleName;
public RootAdminRole(String roleName) {
this.roleName = roleName;
}
@Override
public String op() {
return roleName + " has AAA permission"; }
}
// 訂單管理員(有B操作權限)
public class OrderAdminRole implements RoleOperation {
private String roleName;
public OrderAdminRole(String roleName) {
this.roleName = roleName;
}
@Override
public String op() {
return roleName + " has BBB permission";
}
}
// 普通用戶(有C操作權限)
public class NormalRole implements RoleOperation {
private
String roleName;
public NormalRole
(String roleName) {
this.roleName = roleName;
}
@Override
public String op() {
return roleName + " has CCC permission";
}
}
寫一個工廠類 在靜態塊中 初始化全部工作
public class RoleFactory
{ static Map<String, RoleOperation> roleOperationMap;
// 在靜態塊中先把初始化工作全部做完
static {
roleOperationMap = new HashMap<>();
roleOperationMap.put("ROLE_ROOT_ADMIN", new RootAdminRole("ROLE_ROOT_ADMIN"));
roleOperationMap.put("ROLE_ORDER_ADMIN", new OrderAdminRole("ROLE_ORDER_ADMIN"));
roleOperationMap.put("ROLE_NORMAL", new NormalRole("ROLE_NORMAL"));
}
public static RoleOperation getOp(String roleName) { return roleOperationMap.get(roleName); }
}
簡單使用
RoleFactory.getOp(roleName).op()
這樣的話以後想擴展條件也很容易,只需要增加新代碼,而不需要動以前的業務代碼,非常符合“開閉原則”。
4【策略模式】也很香
在工廠模式的 第一步 “先寫好每個 角色對應的行爲 和 具體動作” 之後,寫一個策略模式的上下文類;
public class RoleContext{
// 可更換的策略,傳入不同的策略對象,業務即相應變化
private RoleOperation operation;
public RoleContext(RoleOperation operation)
{ this.operation = operation;}
public String execute()
{ return operation.op(); }
}
簡單使用
public class JudgeRole {
public String judge(RoleOperation roleOperation) {
RoleContext roleContext = new RoleContext(roleOperation);
return roleContext.execute();
}
}
public static void main(String[] args) {
JudgeRole judgeRole = new JudgeRole();
String result1 = judgeRole.judge(new RootAdminRole("ROLE_ROOT_ADMIN"));
System.out.println(result1);
String result2 = judgeRole.judge(new OrderAdminRole("ROLE_ORDER_ADMIN"));
System.out.println(result2);
String result3 = judgeRole.judge(new NormalRole("ROLE_NORMAL"));
System.out.println(result3);
}