AVt天堂网 手机版,亚洲va久久久噜噜噜久久4399,天天综合亚洲色在线精品,亚洲一级Av无码毛片久久精品

當前位置:首頁 > 科技  > 軟件

規則執行器:告別冗余IF判斷,讓代碼更優雅高效

來源: 責編: 時間:2024-07-03 10:11:47 118觀看
導讀最近公司有個小需求,需要對之前已有的試用用戶申請規則進行拓展。我們的場景大概如下所示:if (是否海外用戶) { return false;}if (刷單用戶) { return false;}if (未付費用戶 && 不再服務時段) { return false}if (

最近公司有個小需求,需要對之前已有的試用用戶申請規則進行拓展。我們的場景大概如下所示:2ef28資訊網——每日最新資訊28at.com

if (是否海外用戶) { return false;}if (刷單用戶) {  return false;}if (未付費用戶 && 不再服務時段) {  return false}if (轉介紹用戶 || 付費用戶 || 內推用戶) {  return true;}

按照上述的條件我們可以得出的結論是:2ef28資訊網——每日最新資訊28at.com

  1. 咱們的的主要流程主要是基于and 或者or 的關系。
  2. 如果有一個不匹配的話,其實咱們后續的流程是不用執行的,就是需要具備一個短路的功能。
  3. 對于目前的現狀來說,我如果在原有的基礎上來改,只要稍微注意一下解決需求不是很大的問題,但是說后面可維護性非常差。

后面經過權衡過后,我還是決定將這個部分進行重構一下。2ef28資訊網——每日最新資訊28at.com

規則執行器

針對這個需求,我首先梳理了一下咱們規則執行器大概的設計, 然后我設計了一個 V1 版本和大家一起分享一下,如果大家也有這樣的 case 可以給我分享留言,下面部分主要是設計和實現的流程和 code。2ef28資訊網——每日最新資訊28at.com

規則執行器的設計

規則處理邏輯優化規則處理邏輯優化2ef28資訊網——每日最新資訊28at.com

2ef28資訊網——每日最新資訊28at.com

對于規則的抽象并實現規則

// 業務數據@Datapublic class RuleDto {  private String address; private int age;}// 規則抽象public interface BaseRule {    boolean execute(RuleDto dto);}// 規則模板public abstract class AbstractRule implements BaseRule {    protected <T> T convert(RuleDto dto) {        return (T) dto;    }    @Override    public boolean execute(RuleDto dto) {        return executeRule(convert(dto));    }      protected <T> boolean executeRule(T t) {        return true;    }}// 具體規則- 例子1public class AddressRule extends AbstractRule {    @Override    public boolean execute(RuleDto dto) {        System.out.println("AddressRule invoke!");        if (dto.getAddress().startsWith(MATCH_ADDRESS_START)) {            return true;        }        return false;    }}// 具體規則- 例子2public class NationalityRule extends AbstractRule {    @Override    protected <T> T convert(RuleDto dto) {        NationalityRuleDto nationalityRuleDto = new NationalityRuleDto();        if (dto.getAddress().startsWith(MATCH_ADDRESS_START)) {            nationalityRuleDto.setNationality(MATCH_NATIONALITY_START);        }        return (T) nationalityRuleDto;    }    @Override    protected <T> boolean executeRule(T t) {        System.out.println("NationalityRule invoke!");        NationalityRuleDto nationalityRuleDto = (NationalityRuleDto) t;        if (nationalityRuleDto.getNationality().startsWith(MATCH_NATIONALITY_START)) {            return true;        }        return false;    }}// 常量定義public class RuleConstant {    public static final String MATCH_ADDRESS_START= "北京";    public static final String MATCH_NATIONALITY_START= "中國";}

執行器構建

public class RuleService {    private Map<Integer, List<BaseRule>> hashMap = new HashMap<>();    private static final int AND = 1;    private static final int OR = 0;    public static RuleService create() {        return new RuleService();    }    public RuleService and(List<BaseRule> ruleList) {        hashMap.put(AND, ruleList);        return this;    }    public RuleService or(List<BaseRule> ruleList) {        hashMap.put(OR, ruleList);        return this;    }    public boolean execute(RuleDto dto) {        for (Map.Entry<Integer, List<BaseRule>> item : hashMap.entrySet()) {            List<BaseRule> ruleList = item.getValue();            switch (item.getKey()) {                case AND:                    // 如果是 and 關系,同步執行                    System.out.println("execute key = " + 1);                    if (!and(dto, ruleList)) {                        return false;                    }                    break;                case OR:                    // 如果是 or 關系,并行執行                    System.out.println("execute key = " + 0);                    if (!or(dto, ruleList)) {                        return false;                    }                    break;                default:                    break;            }        }        return true;    }    private boolean and(RuleDto dto, List<BaseRule> ruleList) {        for (BaseRule rule : ruleList) {            boolean execute = rule.execute(dto);            if (!execute) {                // and 關系匹配失敗一次,返回 false                return false;            }        }        // and 關系全部匹配成功,返回 true        return true;    }    private boolean or(RuleDto dto, List<BaseRule> ruleList) {        for (BaseRule rule : ruleList) {            boolean execute = rule.execute(dto);            if (execute) {                // or 關系匹配到一個就返回 true                return true;            }        }        // or 關系一個都匹配不到就返回 false        return false;    }}

執行器的調用

public class RuleServiceTest {    @org.junit.Test    public void execute() {        //規則執行器        //優點:比較簡單,每個規則可以獨立,將規則,數據,執行器拆分出來,調用方比較規整        //缺點:數據依賴公共傳輸對象 dto        //1. 定義規則  init rule        AgeRule ageRule = new AgeRule();        NameRule nameRule = new NameRule();        NationalityRule nationalityRule = new NationalityRule();        AddressRule addressRule = new AddressRule();        SubjectRule subjectRule = new SubjectRule();        //2. 構造需要的數據 create dto        RuleDto dto = new RuleDto();        dto.setAge(5);        dto.setName("張三");        dto.setAddress("北京");        dto.setSubject("數學");;        //3. 通過以鏈式調用構建和執行 rule execute        boolean ruleResult = RuleService                .create()                .and(Arrays.asList(nationalityRule, nameRule, addressRule))                .or(Arrays.asList(ageRule, subjectRule))                .execute(dto);        System.out.println("this student rule execute result :" + ruleResult);    }}

總結

規則執行器的優點和缺點2ef28資訊網——每日最新資訊28at.com

  • 優點:

比較簡單,每個規則可以獨立,將規則,數據,執行器拆分出來,調用方比較規整;2ef28資訊網——每日最新資訊28at.com

我在 Rule 模板類中定義 convert 方法做參數的轉換這樣可以能夠,為特定 rule 需要的場景數據提供拓展。2ef28資訊網——每日最新資訊28at.com

  • 缺點:上下 rule 有數據依賴性,如果直接修改公共傳輸對象 dto 這樣設計不是很合理,建議提前構建數據。

本文鏈接:http://www.tebozhan.com/showinfo-26-98418-0.html規則執行器:告別冗余IF判斷,讓代碼更優雅高效

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: C#字符串處理技術詳解,你學會了嗎?

下一篇: .NET Core MVC 頁面傳值方式詳解

標簽:
  • 熱門焦點
Top