자바 다 중 조건 판단 장면 에서 규칙 집행 기의 디자인

비 즈 니스 장면
최근 에 회사 에서 작은 수 요 를 얻 었 기 때문에 기 존의 시용 사용자 신청 규칙 을 확대 해 야 한다.우리 의 장면 은 대략 다음 과 같다.

if (      ) {
 return false;
}

if (    ) {
  return false;
}

if (      &&       ) {
  return false
}

if (      ||      ||     ) {
  return true;
}

상술 한 조건 에 따라 우리 가 얻 을 수 있 는 결론 은:
4.567917.우리 의 주요 절 차 는 주로 and 또는 or 의 관 계 를 바탕 으로 한다4.567917.만약 에 일치 하지 않 는 것 이 있다 면 사실은 우리 의 후속 절 차 는 집행 하지 않 아 도 되 고 단락 된 기능 을 가 져 야 한다4.567917.현재 의 현황 에 있어 서 제 가 기 존의 토대 에서 이 를 해 야 한다 면 수 요 를 해결 하 는 데 큰 문제 가 되 지 않 지만 뒤의 유지 가능성 이 매우 떨어진다 고 말 합 니 다뒤에 저울질 을 한 후에 나 는 이 부분 을 재 구성 하기 로 결정 했다.
규칙 실행 기
이 수요 에 따라 저 는 먼저 저희 규칙 집행 기의 대략적인 디자인 을 정리 한 다음 에 V1 버 전 을 디자인 하여 여러분 과 함께 공유 하 겠 습 니 다.만약 에 여러분 도 이런 케이스 가 있 으 면 저 에 게 메 시 지 를 공유 할 수 있 습 니 다.아래 부분 은 주로 디자인 과 실현 의 절차 와 code 입 니 다.
규칙 실행 기 디자인

규칙 에 대한 추상 적 이 고 규칙 을 실현 하 다.

//     
@Data
public 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;
    }
}

//     -   1
public 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;
    }
}

//     -   2
public 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);
    }
}

총결산
규칙 실행 기의 장점 과 단점
장점:
비교적 간단 하고 모든 규칙 은 독립 적 으로 규칙,데이터,집행 기 를 분리 할 수 있 으 며 호출 자가 비교적 정연 하 다.
저 는 Rule 템 플 릿 류 에서 convert 방법 을 매개 변수 로 전환 하면 특정한 rule 에 필요 한 장면 데 이 터 를 확대 할 수 있 습 니 다.
단점:상하 rule 은 데이터 의존 성 이 있 습 니 다.공공 전송 대상 dto 를 직접 수정 하 는 것 이 합 리 적 이지 않 으 면 데 이 터 를 미리 구축 하 는 것 을 권장 합 니 다.
자바 다 중 조건 판단 장면 의 규칙 집행 기 디자인 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.자바 다 중 조건 판단 규칙 집행 기 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 바 랍 니 다!

좋은 웹페이지 즐겨찾기