多个if/else时,替代方案3个案例讲解

一般来说我们正常的后台管理系统都有所谓的角色的概念,不同管理员权限不一样,
能够行使的操作也不一样,比如:
系统管理员( ROLE_ROOT_ADMIN):有 A操作权限
订单管理员( ROLE_ORDER_ADMIN):有 B操作权限
普通用户( ROLE_NORMAL):有 C操作权限

传统的判断方法是一串的if else 代码臃肿

传统方式的if else判断

package com.ruoyi.web.controller.platform;

import com.ruoyi.web.controller.platform.IfelseEnum.JudgeRole;
import com.ruoyi.web.controller.platform.IfelseEnum.RoleOperation;
import com.ruoyi.web.controller.platform.IfelseFactory.RootAdminRole;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;


@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ReplaceIfelse.class)
public class ReplaceIfelse {
    private final static Logger logger = LoggerFactory.getLogger(ReplaceIfelse.class);

    /**
     * 传统方法
     * @param roleName
     * @return
     */
    public String judge(String roleName){
        String result="";
        if(roleName.equals("ROLE_ROOT_ADMIN")){
            result ="ROLE_ROOT_ADMIN"+"has AAA permission";
        }else if (roleName.equals("ROLE_ORDER_ADMIN")){
            result ="ROLE_ORDER_ADMIN"+"has BBB permission";
        }else if (roleName.equals("ROLE_NORMAL")){
            result ="ROLE_NORMAL"+"has CCC permission";
        }else {
            result ="XXX";
        }
        return result;
    }
}

枚举方式替代if else

package com.ruoyi.web.controller.platform.IfelseEnum;

import org.springframework.stereotype.Service;

/**
 * 我们将不同角色的情况全部交由枚举类来做,定义一个不同角色有不同权限的枚举类
 */
@Service
public enum RoleEnum implements RoleOperation {

    ROLE_ROOT_ADMIN {
        @Override
        public String op() {
            return "ROLE_ROOT_ADMIN" + "has AAA permission" ;
        }
    },
    ROLE_ORDER_ADMIN {
        @Override
        public String op() {
            return "ROLE_ORDER_ADMIN" + "has BBB permission" ;
        }
    },
    ROLE_NORMAL {
        @Override
        public String op() {
            return "ROLE_NORMAL" + "has CCC permission" ;
        }
    }
}

工厂方式替代 if else

系统管理员

package com.ruoyi.web.controller.platform.IfelseFactory;

import com.ruoyi.web.controller.platform.IfelseEnum.RoleOperation;
import org.springframework.stereotype.Service;

/**
 * 系统管理员(有A操作权限)
 */
@Service
public class RootAdminRole implements RoleOperation {

    private String roleName;

    public RootAdminRole(String roleName) {
        this.roleName = roleName;
    }

    @Override
    public String op() {
        return roleName + "has AAA permission" ;
    }
}

订单管理员

package com.ruoyi.web.controller.platform.IfelseFactory;

import com.ruoyi.web.controller.platform.IfelseEnum.RoleOperation;
import org.springframework.stereotype.Service;
/**
 * 订单管理员(有B操作权限)
 */
@Service
public class OrderAdminRole implements RoleOperation {


    private String roleName;

    public OrderAdminRole(String roleName) {
        this.roleName = roleName;
    }

    @Override
    public String op() {
        return roleName+"has BBB permission";
    }

}

普通管理员

package com.ruoyi.web.controller.platform.IfelseFactory;

import com.ruoyi.web.controller.platform.IfelseEnum.RoleOperation;
import org.springframework.stereotype.Service;
/**
 * 普通管理员(有C操作权限)
 */
@Service
public class NormalRole implements RoleOperation {
    private String roleName;

    public NormalRole(String roleName) {
        this.roleName = roleName;
    }
    @Override
    public String op() {
        return roleName+"has CCC permission";
    }
}

工厂类

package com.ruoyi.web.controller.platform.IfelseFactory;

import com.ruoyi.web.controller.platform.IfelseEnum.RoleOperation;

import java.util.HashMap;
import java.util.Map;

/**
 * 不同分支做不同的事情,很明显就提供了使用工厂模式的契机,我们只需要将不同情况单独定义好,然后去工厂类里面聚合即可。
 * 写一个工厂类 RoleFactory对上面不同角色进行聚合
 */
public class RoleFactory {
    static Map<String, RoleOperation> roleOperationMap=new HashMap<String, RoleOperation>();
    // 在静态块中先把初始化工作全部做完
    static {
        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 roleNeme){
        return roleOperationMap.get(roleNeme);
    }
}

策略方式替代 if else

package com.ruoyi.web.controller.platform.IfelseStrategy;

import com.ruoyi.web.controller.platform.IfelseEnum.RoleOperation;

/**
 * 在上面工厂模式代码的基础上,按照策略模式的指导思想,我们也来创建一个所谓的策略上下文类,这里命名为 RoleContext
 */
public class RoleContext {
    // 可更换的策略,传入不同的策略对象,业务即相应变化
    private RoleOperation operation;

    public RoleContext(RoleOperation operation) {
        this.operation = operation;
    }

    public String execute(){
        return operation.op();
    }
}

公共方法

package com.ruoyi.web.controller.platform.IfelseEnum;

public interface RoleOperation {
    // 表示某个角色可以做哪些op操作
    String op();
}

package com.ruoyi.web.controller.platform.IfelseEnum;

import com.ruoyi.web.controller.platform.IfelseFactory.RoleFactory;
import com.ruoyi.web.controller.platform.IfelseStrategy.RoleContext;

/**
 * 判断Judge角色
 */
public class JudgeRole {
    /**
     * 枚举模式消除if else
     * 而且这样一来,以后假如我想扩充条件,只需要去枚举类中加代码即可,而不是去改以前的代码,这岂不很稳!
     * @param roleName
     * @return
     */
    public String judgeEnum (String roleName){
        String op = RoleEnum.valueOf(roleName).op();
        return op;
    }

    /**
     * 工厂模式消除if else
     * 接下来借助上面这个工厂,业务代码调用也只需一行代码, if/else同样被消除了:
     * @param roleName
     * @return
     */
    public String judgeFactory(String roleName){
        String op = RoleFactory.getOp(roleName).op();
        return op;
    }

    /**
     * 策略模式消除if else
     * @return
     */
    public String judgeStrategy(RoleOperation roleOperation){
        RoleContext roleContext=new RoleContext(roleOperation);
        return roleContext.execute();
    }


}

测试上述3种方式

package com.ruoyi.web.controller.platform;

import com.ruoyi.web.controller.platform.IfelseEnum.JudgeRole;
import com.ruoyi.web.controller.platform.IfelseEnum.RoleOperation;
import com.ruoyi.web.controller.platform.IfelseFactory.RootAdminRole;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ReplaceIfelse.class)
public class ReplaceIfelse {
    private final static Logger logger = LoggerFactory.getLogger(ReplaceIfelse.class);

    @Test
    public void judgeIfelse(){
        JudgeRole judgeRole=new JudgeRole();
        String roleRootAdmin = judgeRole.judgeEnum("ROLE_ROOT_ADMIN");
        String roleOrderAdmin = judgeRole.judgeEnum("ROLE_ORDER_ADMIN");
        String roleNormal = judgeRole.judgeEnum("ROLE_NORMAL");
        logger.info(">>>>枚举方式获取角色权限:{}>>>>",roleRootAdmin +"___"+ roleOrderAdmin+"___"+roleNormal);
        String roleRootAdmin1 = judgeRole.judgeFactory("ROLE_ROOT_ADMIN");
        String roleOrderAdmin1 = judgeRole.judgeFactory("ROLE_ORDER_ADMIN");
        String roleNormal1 = judgeRole.judgeFactory("ROLE_NORMAL");
        logger.info(">>>>工厂方式获取角色权限:{}>>>>",roleRootAdmin1 +"___"+ roleOrderAdmin1+"___"+roleNormal1);
        String roleRootAdmin2 = judgeRole.judgeStrategy(new RootAdminRole("ROLE_ROOT_ADMIN"));
        String roleOrderAdmin2 = judgeRole.judgeStrategy(new RootAdminRole("ROLE_ORDER_ADMIN"));
        String roleNormal2 = judgeRole.judgeStrategy(new RootAdminRole("ROLE_NORMAL"));
        logger.info(">>>>策略方式获取角色权限:{}>>>>",roleRootAdmin1 +"___"+ roleOrderAdmin1+"___"+roleNormal1);
    }
}

结果

>>>>枚举方式获取角色权限:ROLE_ROOT_ADMINhas AAA permission___ROLE_ORDER_ADMINhas BBB permission___ROLE_NORMALhas CCC permission>>>>
>>>>工厂方式获取角色权限:ROLE_ROOT_ADMINhas AAA permission___ROLE_ORDER_ADMINhas BBB permission___ROLE_NORMALhas CCC permission>>>>
>>>>策略方式获取角色权限:ROLE_ROOT_ADMINhas AAA permission___ROLE_ORDER_ADMINhas BBB permission___ROLE_NORMALhas CCC permission>>>>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章