如何告别 if else

实际例子:不同管理员权限不一样,能够行使的操作也不一样。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
publicclassJudgeRole{
publicString judge(String roleName ) {
String result = "";
if (roleName.equals( "ROLE_ROOT_ADMIN" )) { // 系统管理员有A权限
result = "ROLE_ROOT_ADMIN: " + "has AAA permission" ;
}elseif( roleName.equals("ROLE_ORDER_ADMIN") ) { // 订单管理员有B权限
result = "ROLE_ORDER_ADMIN: " + "has BBB permission" ;
}elseif( roleName.equals("ROLE_NORMAL") ) {// 普通用户有C权限
result = "ROLE_NORMAL: " + "has CCC permission" ;
}else{
result = "XXX" ;
}
return result;
}
}

枚举

什么角色能干什么事,这很明显有一个对应关系。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// 首先定义一个公用接口 RoleOperation,表示不同角色所能做的操作:
publicinterfaceRoleOperation{
String op(); // 表示某个角色可以做哪些op操作
}

// 将不同角色的情况全部交由枚举类来做,定义一个不同角色有不同权限的枚举类 RoleEnum:
publicenumRoleEnumimplementsRoleOperation{
// 系统管理员(有A操作权限)
ROLE_ROOT_ADMIN {
@Override
publicString op() {
return "ROLE_ROOT_ADMIN:" + " has AAA permission";
}
},
// 订单管理员(有B操作权限)
ROLE_ORDER_ADMIN {
@Override
publicString op() {
return "ROLE_ORDER_ADMIN:" + " has BBB permission";
}
},
// 普通用户(有C操作权限)
ROLE_NORMAL {
@Override
publicString op() {
return "ROLE_NORMAL:" + " has CCC permission";
}
},
}
// 调用
publicclassJudgeRole {
publicString judge( String roleName ) {
// 一行代码搞定!之前的if/else没了!
returnRoleEnum.valueOf(roleName).op();
}
}

工厂模式

不同分支做不同的事情,很明显就提供了使用工厂模式的契机,我们只需要将不同情况单独定义好,然后去工厂类里面聚合即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
// 针对不同的角色,单独定义其业务类:
// 系统管理员(有 A 操作权限)

publicclassRootAdminRoleimplementsRoleOperation {
privateString roleName;
publicRootAdminRole(String roleName ) {
this.roleName = roleName;
}
@Override
publicString op() {
return roleName + " has AAA permission" ;
}

}

// 订单管理员(有 B 操作权限)

publicclassOrderAdminRoleimplementsRoleOperation {
privateString roleName;
publicOrderAdminRole( String roleName ) {
this.roleName = roleName;
}
@Override
publicString op() {
return roleName + " has BBB permission";
}
}

// 普通用户(有 C 操作权限)

publicclassNormalRoleimplementsRoleOperation {
privateString roleName;
publicNormalRole( String roleName ) {
this.roleName = roleName;
}
@Override
publicString op() {
return roleName + " has CCC permission";
}
}

// 接下来再写一个工厂类 RoleFactory对上面不同角色进行聚合:
publicclassRoleFactory {
staticMap < String, RoleOperation > roleOperationMap = newHashMap <>();
// 在静态块中先把初始化工作全部做完
static{
roleOperationMap.put( "ROLE_ROOT_ADMIN", newRootAdminRole("ROLE_ROOT_ADMIN") );
roleOperationMap.put( "ROLE_ORDER_ADMIN", newOrderAdminRole("ROLE_ORDER_ADMIN") );
roleOperationMap.put( "ROLE_NORMAL", newNormalRole("ROLE_NORMAL") );
}

publicstaticRoleOperation getOp( String roleName ) {
return roleOperationMap.get( roleName );
}
}

// 调用

publicclassJudgeRole{
publicString judge( String roleName ) {
// 一行代码搞定!之前的 if/else也没了!
returnRoleFactory.getOp(roleName).op();
}
}

策略模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

// 按照策略模式的指导思想,我们也来创建一个所谓的策略上下文类,这里命名为 RoleContext:

publicclassRoleContext {
// 可更换的策略,传入不同的策略对象,业务即相应变化
privateRoleOperation operation;
publicRoleContext( RoleOperation operation ) {
this.operation = operation;
}
publicString execute() {
return operation.op();
}
}

//很明显上面传入的参数 operation就是表示不同的“策略”。我们在业务代码里传入不同的角色,即可得到不同的操作结果

publicclassJudgeRole {
publicString judge( RoleOperation roleOperation ) {
RoleContext roleContext = newRoleContext( roleOperation );
return roleContext.execute();
}
}

publicstaticvoid main( String[] args ) {
JudgeRole judgeRole = newJudgeRole();
String result1 = judgeRole.judge( newRootAdminRole("ROLE_ROOT_ADMIN"));
System.out.println( result1 );
String result2 = judgeRole.judge( newOrderAdminRole("ROLE_ORDER_ADMIN"));
System.out.println( result2 );
String result3 = judgeRole.judge( newNormalRole("ROLE_NORMAL"));
System.out.println( result3 );
}

参考文章
答应我,别再 if/else 走天下了可以吗?

作者

Fallen-down

发布于

2020-01-24

更新于

2020-01-24

许可协议

You need to set install_url to use ShareThis. Please set it in _config.yml.
You forgot to set the business or currency_code for Paypal. Please set it in _config.yml.

评论

You forgot to set the shortname for Disqus. Please set it in _config.yml.
You need to set client_id and slot_id to show this AD unit. Please set it in _config.yml.