代码重构:过长参数列表
        【摘要】 代码重构:过长参数列表
    
    
    
    什么是过长参数列表(Long Parameter List)
-  定义:方法的入参过多,或存在不必要的参数 
-  影响:方法不易被理解、使用,方法签名容易不稳定,不易维护 
-  改进目标:去除多余参数,合并部分参数,提升方法签名稳定性 
-  方法: -  以查询取代参数 
-  保持对象完整 
-  引入参数对象 
-  函数组合成类 
-  移除标记参数 
 
-  
-  注:有时候你明显不希望造成“被调用对象”与“较大对象”间的某种依赖关系。这时候将数据从对象中拆解出来单独作为参数,也很合情合理。但是请注意其所引发的代价。如果参数列太长或变化太频繁,你就需要重新考虑自己的依赖结构了。 
代码案例
public class TicketInfo {
    private final double baseDiscount;
    public TicketInfo(double baseDiscount) {
        this.baseDiscount = baseDiscount;
    }
    /**
     * 获取票据信息
     * 
     * @param name 姓名
     * @param age 年龄
     * @param isChild 是否儿童
     * @param isStudent 是否学生
     * @param ageFloor 年龄上限
     * @param ageCeiling 年龄下限
     * @param performance 演出信息
     * @param basicPrice 基本票价
     * @return 票据信息
     */
    public String getTicketInfo(String name, int age, boolean isChild, boolean isStudent, int ageFloor, int ageCeiling,
        Performance performance, double basicPrice) {
        if ((age < ageFloor || age > ageCeiling)) {
            throw new IllegalArgumentException("age is out of valid range, cannot buy ticket!");
        }
        return getPerformanceInfo(performance)
            + getConsumerInfo(name, age, isStudent, isChild)
            + getPriceInfo(isChild, isStudent, basicPrice);
    }
    private String getPriceInfo(boolean isChild, boolean isStudent, double basicPrice) {
        final double discount = getDiscount(isStudent, isChild);
        final double ticketPrice = getTicketPrice(discount, basicPrice);
        return "priceInfo" + Constant.LINE_SEPARATOR
            + "\tprice: " + ticketPrice + Constant.LINE_SEPARATOR
            + "\tdiscount: " + discount + Constant.LINE_SEPARATOR;
    }
    private double getDiscount(boolean isStudent, boolean isChild) {
        double childDiscount = calculateDiscount("Child", isChild, isStudent);
        double studentDiscount = calculateDiscount("Student", isChild, isStudent);
        return BigDecimal.valueOf(Math.min(childDiscount, studentDiscount))
            .setScale(2, BigDecimal.ROUND_HALF_UP)
            .doubleValue();
    }
    private double calculateDiscount(String discountType, boolean isChild, boolean isStudent) {
        if ("Child".equals(discountType) && isChild) {
            return 0.5;
        }
        if ("Student".equals(discountType) && isStudent) {
            return 0.9 * baseDiscount;
        }
        return baseDiscount;
    }
    private double getTicketPrice(double discount, double basicPrice) {
        return BigDecimal.valueOf(discount * basicPrice).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
    }
    private String getConsumerInfo(String name, int age, boolean isStudent, boolean isChild) {
        return "consumerInfo" + Constant.LINE_SEPARATOR
            + "\tname: " + name + Constant.LINE_SEPARATOR
            + "\tage: " + age + Constant.LINE_SEPARATOR
            + "\tisStudent: " + isStudent + Constant.LINE_SEPARATOR
            + "\tisChild: " + isChild + Constant.LINE_SEPARATOR;
    }
    private String getPerformanceInfo(Performance performance) {
        return "playInfo" + Constant.LINE_SEPARATOR
            + "\tplayName: " + performance.getPlayName() + Constant.LINE_SEPARATOR
            + "\tplayType: " + performance.getPlayType() + Constant.LINE_SEPARATOR
            + "\tdate: " + performance.getPlayDate() + Constant.LINE_SEPARATOR;
    }
}代码背景
-  计算某表演项目的票价; 
-  只有符合年龄要求才可以购买,; 
-  儿童票5折, 学生可以打9折, 二者取最小; 
症状/问题:方法入参过多,该问题的具体情况有:
-  某几个入参有关联性 
-  某几个入参是一个对象的部分字段 
-  某些入参可通过其他入参计算得到 

代码背景
-  计算某表演项目的票价; 
-  只有符合年龄要求才可以购买,; 
-  儿童票5折, 学生可以打9折, 二者取最小; 
症状/问题
-  函数逻辑都是针对某个入参对象属性的加工 
-  某些入参属于标记,用于控制代码逻辑 

-  查询取代参数、保持对象完整、引入参数对象 

-  移动函数至适合的类、移除标记参数 

相关技巧
华为编程规范

可运行CodeCheck来辅助排查是否存在过长参数列表的坏味道:

总结
            【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
                cloudbbs@huaweicloud.com
                
            
        
        
        
        
        - 点赞
- 收藏
- 关注作者
 
            
 
           
评论(0)