一、实况概述
对于多种判断,在代码中遇到的情况太多了,今天我们拿管理员权限举个🌰。
一般来说我们正常的后台管理系统都有所谓的角色概念,不同管理员权限是不一样的,能够行使的操作也不一样:
- 系统管理员(ROLE_ROOT_ADMIN) :有A操作权限
- 订单管理员(ROLE_ORDER_ADMIN):有B操作权限
- 普通管理员(ROLE_NORMAL):有C操作权限
一个用户登陆进来,我们根据用户不同角色来判断哪些行为;
强行代码一波:
这种是最顺手的, 只要手够快,脑子都跟不上代码;也是平时写的最多的。
这样当系统里有几十个角色时,那几十个 if/else嵌套可以说是非常酸爽了…… 这样一来非常不优雅,别人阅读起来很费劲;二来则是以后如果再复杂一点,或者想要再加条件的话不好扩展;而且代码一改,以前的老功能肯定还得重测,岂不疯了……
今天我们来说说高逼格的方法。。开始我们的Code Show。。
二、最香的枚举
什么角色能干什么事,这明显就是一个对应关系,所以为什么不用枚举呢?
首先定义一个公用的接口RoleOperation,表示不同角色所能做的操作:
interface RoleOperation {
fun op() : String 表示某个角色可以做哪些OP操作
}
接下来我们将不同角色的情况全部交由枚举类来做,定义一个不同角色有不同权限的枚举类RoleEnum:
enum class RoleEnum : RoleOperation {
ROLE_ROOT_ADMIN {
override fun op(): String {
return Constants.Role().ROLE_ROOT_ADMIN + " : " + "has A Permisiion"
}
},
ROLE_ORDER_ADMIN {
override fun op(): String {
return Constants.Role().ROLE_ORDER_ADMIN + " : " + "has B permission"
}
},
ROLE_NORMAL {
override fun op(): String {
return Constants.Role().ROLE_NORMAL + " : " + "has C permission"
}
}
}
这样调用就变的异常简单了,一行代码就行了
/**
* 使用枚举方法
*/
fun judgeUserEnum(roleName : String) : String
{
return RoleEnum.valueOf(roleName).op()
}
这样的好处就在于以后要扩展条件, 只需要在枚举类中增加代码即可,而不用去修改以前的代码。
三、高逼格的工厂模式
不同分支做不同的事情,很明显提供了使用工厂模式的契机,我们只需要将不同情况单独定义好,然后去工厂类中聚合就行。
如下图,我们将不同的管理权限单独定义在role包里,然后在RoleFactory中对权限进行整合
第一步、将不同权限单独定义
/**
* 普通用户 有C权限
*/
class NormalRole(roleName : String): RoleOperation {
var roleNamevalue = roleName
override fun op(): String {
return roleNamevalue + " : " + "has C permisiion"
}
}
/**
* 订单管理员 有B权限
*/
class OrderAdmin(roleName : String) : RoleOperation
{
var roleNameValue = roleName
override fun op(): String {
return roleNameValue + " : " + "has B permission"
}
}
/**
* 系统管理员 有A权限
*/
class RootAdmin(roleName : String) : RoleOperation
{
var roleNameValue = roleName
override fun op(): String {
return roleNameValue + " : " + "Has A permission"
}
}
第二步、对上面不同角色进行聚合
class RoleFactory{
var roleOperationMap = mutableMapOf<String,RoleOperation>()
//在初始化中聚合所有情况
init {
roleOperationMap.put(Constants.Role().ROLE_ROOT_ADMIN,RootAdmin(Constants.Role().ROLE_ROOT_ADMIN))
roleOperationMap.put(Constants.Role().ROLE_ORDER_ADMIN,OrderAdmin(Constants.Role().ROLE_ORDER_ADMIN))
roleOperationMap.put(Constants.Role().ROLE_NORMAL,NormalRole(Constants.Role().ROLE_NORMAL))
}
fun getOp(roleName : String) : RoleOperation{
return roleOperationMap.getValue(roleName)
}
}
第三步、借助上面的工厂,调用业务逻辑代码
/**
* 使用工厂模式
*/
fun judgeUsefactory(roleName: String) : String
{
return RoleFactory().getOp(roleName).op()
}
这样的话以后想扩展条件也很容易,只需要增加新的权限代码,而不需要动以前的业务代码
四、高逼格的策略模式
根据不同的策略对象,发生不同的业务变化,就是策略模式
class RoleContext(operation : RoleOperation){
//根据传入的策略对象,执行不同的逻辑对象
var operationValue = operation
fun execute() : String{
return operationValue.op()
}
}
很明显上面传入的参数 operation就是表示不同的“策略”。我们在业务代码里传入不同的角色,即可得到不同的操作结果
/**
* 使用策略模式
*/
fun judgeUseContext(operation: RoleOperation) : String
{
return RoleContext(operation).execute()
}
五、测试用例
fun main(args: Array<String>) {
//If Else方式
var s1: String = JudgeRole().judgeUseIfElse(Constants.Role().ROLE_ROOT_ADMIN)
println(s1)
//枚举方式
var s2: String = JudgeRole().judgeUserEnum(Constants.Role().ROLE_ORDER_ADMIN)
println(s2)
var s3 = JudgeRole().judgeUsefactory(Constants.Role().ROLE_NORMAL)
println(s3)
var s4 =JudgeRole().judgeUseContext(RootAdmin(Constants.Role().ROLE_ROOT_ADMIN))
println(s4)
}
六、下载地址
完整DEMO地址: