(4/8)枚举的错误用法 之 方法返回值


▄︻┻┳═一Agenda:

▄︻┻┳═一(1/8)[代码整洁之道]你真的会用枚举吗?非也!

▄︻┻┳═一(2/8)枚举的错误用法 之 方法参数

▄︻┻┳═一(3/8)枚举的错误用法 之 方法参数(二)

▄︻┻┳═一(4/8)枚举的错误用法 之 方法返回值

▄︻┻┳═一(5/8)枚举的错误用法 之 方法体内部

▄︻┻┳═一(6/8)枚举的错误用法 之 分支判断

▄︻┻┳═一(7/8)借助枚举说一下数据类型定义规范

▄︻┻┳═一(8/8)RPC接口能用枚举就请考虑枚举


继续讲枚举的使用。本文举例说明方法返回值使用枚举类型对程序可读性和可维护性的影响。

【先上代码】

如下代码逻辑比较简单:判断bizType和cardType不同情况下的取值,来给字符串channelType赋值,并最终返回这个字符串。

// PpdUtils.java

/**
 * 获取通道类型
 *
 * @param bizType
 * @param cardType
 * @return
 */
public static String getChannelType(String bizType, String cardType) {
    String channelType = "";
    BizTypeEnum bizTypeDict = BizTypeEnum.getByKey(bizType);

    switch (bizTypeDict) {
        case B2C_CHARGE:
        case B2C_CONSUME_COMPLETION:
        case GWAY_CONSUME_COMPLETION:
        case B2C_ENT_CONSUME_COMPLETION:
        case B2C_ENT_REPAYMENT:
        case PGW_GW_COMPLETION:
        case CREDIT_PAY_COMPLETION:
        case CREDIT_PAY_COMPLETION_REFUND:
            channelType = ChannelTypeEnum.B2C.getValue();

            break;

        case B2B_CHARGE:
        case B2B_CHARGE_FOR_ENT:
        case B2B_CHARGE_ORDER_ADDITIONAL:
        case B2B_ENT_CONSUME_COMPLETION:
        case B2B_ENT_REPAYMENT:
        case PGW_B2B_COMPLETION:
            channelType = ChannelTypeEnum.B2B.getValue();

            break;

        case QPAY_CONSUME_COMPLETION:
        case QUICK_CHARGE:
        case PGW_QPAY_COMPLETION:

            if (CardTypeEnum.CreditCard.equals(cardType)) {
                channelType = ChannelTypeEnum.CQP.getValue();
            } else {
                channelType = ChannelTypeEnum.DQP.getValue();
            }

            break;

        case OCP_CONSUME_COMPLETION:
        case OCP_ENT_CONSUME_COMPLETION:
        case OCP_ENT_REPAYMENT:
        case OCP_REFUND:
            channelType = ChannelTypeEnum.OCP.getValue();

            break;

        default:
            break;
    }

    return channelType;
}

【重构方式】

本文重点讨论的是方法的返回值。所以呢,对于上面的方法,我们且不说两个入参应该使用枚举类型,其他代码不足之处也请勿喷。

我们注意到,方法体里要返回的变量channelType,在switch的每个分支里,给它的赋值都是ChannelTypeEnum项的value。

那么,显然,这个方法没必要返回字符串了,而应该直接返回ChannelTypeEnum。同样,方法内部的变量channelType的类型重构为ChannelTypeEnum。

这样,相比于返回String,调用方能直观的知道返回值的具体类型及可取值范围,从而提高了可读性。 

重构后的代码为:

// PpdUtils.java

/**
 * 获取通道类型
 *
 * @param bizType
 * @param cardType
 * @return
 */
public static ChannelTypeEnum getChannelType(BizTypeEnum bizType, CardTypeEnum cardType) {
    ChannelTypeEnum channelType = null;switch (bizType) {
        case B2C_CHARGE:
        case B2C_CONSUME_COMPLETION:
        case GWAY_CONSUME_COMPLETION:
        case B2C_ENT_CONSUME_COMPLETION:
        case B2C_ENT_REPAYMENT:
        case PGW_GW_COMPLETION:
        case CREDIT_PAY_COMPLETION:
        case CREDIT_PAY_COMPLETION_REFUND:
            channelType = ChannelTypeEnum.B2C;

            break;

        case B2B_CHARGE:
        case B2B_CHARGE_FOR_ENT:
        case B2B_CHARGE_ORDER_ADDITIONAL:
        case B2B_ENT_CONSUME_COMPLETION:
        case B2B_ENT_REPAYMENT:
        case PGW_B2B_COMPLETION:
            channelType = ChannelTypeEnum.B2B;

            break;

        case QPAY_CONSUME_COMPLETION:
        case QUICK_CHARGE:
        case PGW_QPAY_COMPLETION:

            if (CardTypeEnum.CreditCard == cardType) {
                channelType = ChannelTypeEnum.CQP;
            } else {
                channelType = ChannelTypeEnum.DQP;
            }

            break;

        case OCP_CONSUME_COMPLETION:
        case OCP_ENT_CONSUME_COMPLETION:
        case OCP_ENT_REPAYMENT:
        case OCP_REFUND:
            channelType = ChannelTypeEnum.OCP;

            break;

        default:
            break;
    }

    return channelType;
}