别再 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);
}