策略枚举的用法三:规则处理

476 阅读3分钟

说明

本文只对策略枚举可以使用的场景进行说明,不做其他介绍。提供额外的实现思路。

规则处理

在开发过程中,我们会遇到需要对不同类型的数据进行不同的校验。这时候传统的做法就是写很多的switc 然后case,或者使用if else 这种写法。非常占用主代码内容。但是我们校验的内容又大体一致,所以就可以使用枚举来实现。 例如:索赔类型校验

package com.strategy.cthree;

import java.math.BigDecimal;
import java.util.Date;

/**
 * 类型枚举
 */
public enum TypeEnum {

    /** 三包索赔 */
    THREE_GUARANTEES_CLAIM(1, "三包索赔") {
        @Override
        public boolean check(OrderEntity order) {
            if (order.getThreeDate() != null && order.getThreeDate().compareTo(new Date()) >= 0) {
                System.out.println("已经超过三包期限,不允许进行三包索赔。");
                return false;
            }
            return true;
        }
    },

    /** 配件索赔 */
    PART_CLAIM(2, "配件索赔") {
        @Override
        public boolean check(OrderEntity order) {
            if (order.getPartCode() == null || "".equals(order.getPartCode())) {
                System.out.println("配件索赔必须要有配件编码。");
                return false;
            }
            return true;
        }
    },

    /** 善意索赔 */
    GOODWILL_CLAIM(7, "善意索赔") {
        @Override
        public boolean check(OrderEntity order) {
            if (order.getAmount() != null && order.getAmount().compareTo(new BigDecimal("100")) >= 0 && (order.getApplicationOrder() == null || "".equals(order.getApplicationOrder()))) {
                System.out.println("金额超过100,请先发起申请单。");
                return false;
            }
            return true;
        }
    };

    /** 校验 */
    public abstract boolean check(OrderEntity order);

    public static TypeEnum valueOf(Integer index) {
        if (index == null) {
            return null;
        }
        for (TypeEnum modeEnum : TypeEnum.values()) {
            if (index == modeEnum.getIndex()) {
                return modeEnum;
            }
        }
        return null;
    }

    /** 枚举值 */
    private int index;

    /** 枚举描述 */
    private String name;

    TypeEnum(int index, String name) {
        this.index = index;
        this.name = name;
    }

    public int getIndex() {
        return index;
    }

    public String getName() {
        return name;
    }
}

数据实体

package com.strategy.cthree;

import java.math.BigDecimal;
import java.util.Date;

/**
 * 单据
 */
public class OrderEntity {

    /** 主键ID */
    private Long id;

    /** 类型 */
    private Integer type;

    /** 金额 */
    private BigDecimal amount;

    /** 三包期限 */
    private Date threeDate;

    /** 配件编码 */
    private String partCode;

    /** 申请单 */
    private String applicationOrder;

    public OrderEntity(Long id, Integer type, BigDecimal amount, Date threeDate, String partCode,
                       String applicationOrder) {
        this.id = id;
        this.type = type;
        this.amount = amount;
        this.threeDate = threeDate;
        this.partCode = partCode;
        this.applicationOrder = applicationOrder;
    }

    public Long getId() {
        return id;
    }

    public Integer getType() {
        return type;
    }

    public BigDecimal getAmount() {
        return amount;
    }

    public Date getThreeDate() {
        return threeDate;
    }

    public String getPartCode() {
        return partCode;
    }

    public String getApplicationOrder() {
        return applicationOrder;
    }
}

测试代码

package com.strategy.cthree;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.SimpleFormatter;

/**
 * <类说明>
 * @author <a href="ahong.chen01@ucarinc.com">ahong.chen01</a>
 * @date 2019-12-20 15:27
 * @since 1.0
 */
public class TypeEnumMainTest {

    public static void main(String[] args) throws Exception {
        new TypeEnumMainTest().test();
    }

    private void test() throws ParseException {
        List<OrderEntity> orderList = getOrderList();
        for (OrderEntity order : orderList) {
            boolean b = TypeEnum.valueOf(order.getType()).check(order);
            if (b) {
                System.out.println("ID【" + order.getId() + "】校验通过。\n");
            } else {
                System.out.println("ID【" + order.getId() + "】校验不通过。\n");
            }
        }
    }

    private List<OrderEntity> getOrderList() throws ParseException {
        List<OrderEntity> list = new ArrayList<>();
        // 三包校验不通过
        list.add(new OrderEntity(1L, TypeEnum.THREE_GUARANTEES_CLAIM.getIndex(), new BigDecimal("10"), new SimpleDateFormat("yyyy-MM-dd").parse("2018-12-20"), "partCode1", null));
        // 三包校验通过
        list.add(new OrderEntity(2L, TypeEnum.THREE_GUARANTEES_CLAIM.getIndex(), new BigDecimal("10"), new SimpleDateFormat("yyyy-MM-dd").parse("2040-12-20"), "partCode1", null));
        // 配件校验不通过
        list.add(new OrderEntity(3L, TypeEnum.PART_CLAIM.getIndex(), new BigDecimal("10"), new SimpleDateFormat("yyyy-MM-dd").parse("2040-12-20"), "", null));
        // 配件校验通过
        list.add(new OrderEntity(4L, TypeEnum.PART_CLAIM.getIndex(), new BigDecimal("10"), new SimpleDateFormat("yyyy-MM-dd").parse("2040-12-20"), "partCode1", null));
        // 善意校验不通过
        list.add(new OrderEntity(5L, TypeEnum.GOODWILL_CLAIM.getIndex(), new BigDecimal("1000"), new SimpleDateFormat("yyyy-MM-dd").parse("2040-12-20"), "partCode1", null));
        // 善意校验不通过
        list.add(new OrderEntity(6L, TypeEnum.GOODWILL_CLAIM.getIndex(), new BigDecimal("1000"), new SimpleDateFormat("yyyy-MM-dd").parse("2040-12-20"), "partCode1", "CODE0001"));
        return list;
    }
}

执行结果如下:

ID【1】校验通过。

已经超过三包期限,不允许进行三包索赔。
ID【2】校验不通过。

配件索赔必须要有配件编码。
ID【3】校验不通过。

ID【4】校验通过。

金额超过100,请先发起申请单。
ID【5】校验不通过。

ID【6】校验通过。

通过以上方法,减少代码量,同时如果校验规则变更,也不会影响到其他类型的校验。