別再if-else 走天下了

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

從這個一刻起,我們在設計一些複雜的業務場景時,應該先去考慮其擴展性。把代碼寫的可讀性提高,更加靈活; 加油吧!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章