如何处理Duplicated块

时间:2016-04-01 10:23:51

标签: java duplicates sonarqube

我跑了sonarqube,但它告诉了我错误

Gold&类中的“重复块”银。

我修改了很多东西,但它没有解决问题

这是我的来源

黄金和白银是延伸计划

这是一个Plan.Source

public abstract class Plan {
public abstract double getBasicRate();
public abstract int getBasicMinute();
public abstract double getAdditionalLineRate();
public abstract double getRatePerExcessMinute();
public abstract String getPlanName();}

这是Gold.Source

public class Gold extends Plan {

private static final double BASIC_RATE = 49.95;
private static final int BASIC_MINUTE = 1000;
private static final double ADDITIONAL_LINE_RATE = 14.50;
private static final double RATE_PER_EXCESS_MINUTE = 0.45;
private static final String PLAN_NAME = "Gold";

public double getBasicRate() {
    return BASIC_RATE;
}

public int getBasicMinute() {
    return BASIC_MINUTE;
}

public double getAdditionalLineRate() {
    return ADDITIONAL_LINE_RATE;
}

public double getRatePerExcessMinute() {
    return RATE_PER_EXCESS_MINUTE;
}

public String getPlanName() {
    return PLAN_NAME;
}

}

这是一个Silver.Source

public class Silver extends Plan {

private static final double BASIC_RATE = 29.95;
private static final int BASIC_MINUTE = 500;
private static final double ADDITIONAL_LINE_RATE = 21.50;
private static final double RATE_PER_EXCESS_MINUTE = 0.54;
private static final String PLAN_NAME = "Silver";

public double getBasicRate() {
    return BASIC_RATE;
}

public int getBasicMinute() {
    return BASIC_MINUTE;
}

public double getAdditionalLineRate() {
    return ADDITIONAL_LINE_RATE;
}

public double getRatePerExcessMinute() {
    return RATE_PER_EXCESS_MINUTE;
}

public String getPlanName() {
    return PLAN_NAME;
}

}

请帮帮我

3 个答案:

答案 0 :(得分:2)

Gold和Silver中的代码是相同的,除了分配给变量的数据。你可以重构这样的东西来删除重复:

public class Plan {

    private final double BASIC_RATE;
    private final int BASIC_MINUTE;
    private final double ADDITIONAL_LINE_RATE;
    private final double RATE_PER_EXCESS_MINUTE;
    private final String PLAN_NAME;

    public Plan(double BASIC_RATE, int BASIC_MINUTE,
            double ADDITIONAL_LINE_RATE, double RATE_PER_EXCESS_MINUTE,
            String PLAN_NAME) {
        this.BASIC_RATE = BASIC_RATE;
        this.BASIC_MINUTE = BASIC_MINUTE;
        this.ADDITIONAL_LINE_RATE = ADDITIONAL_LINE_RATE;
        this.RATE_PER_EXCESS_MINUTE = RATE_PER_EXCESS_MINUTE;
        this.PLAN_NAME = PLAN_NAME;
    }

    public double getBasicRate() {
        return BASIC_RATE;
    }

    public int getBasicMinute() {
        return BASIC_MINUTE;
    }

    public double getAdditionalLineRate() {
        return ADDITIONAL_LINE_RATE;
    }

    public double getRatePerExcessMinute() {
        return RATE_PER_EXCESS_MINUTE;
    }

    public String getPlanName() {
        return PLAN_NAME;
    }
}

然后Gold看起来像这样:

public class Gold extends Plan {

    public Gold() {
        super(49.95, 1000, 14.50, 0.45, "Gold");
    }
}

我们在这里所做的是获取由2个类共享的代码并将其移动到其父类中。通过调用Gold中的超级构造函数,我们将变量分配给超类Plan的此实现所需的值。

我们还从类变量中删除了static。这意味着变量将与类的实例相关,而不是与类本身相关 我们这样做是为了使Plan中的变量与Plan的每个实例相关联。这意味着我们可以在扩展类中使用它们而不会混合数据 在很多情况下,除非您主动想要在没有类实例的情况下访问变量,否则通常不会使用static。您可以详细了解static here

答案 1 :(得分:0)

如果你真的想拥有一个像这样的单独的Gold和Silver类,你就无法避免重复的代码块。您可以通过在导致违规的行上方添加以下行来抑制声纳违规(请参阅Sonar FAQ):

// NOSONAR

或者,您可以使用枚举来表示这些值:

public enum Plan {

    GOLD(49.95, 1000, 14.50, 0.45, "Gold"),
    SILVER(29.95, 500, 21.50, 0.54, "Silver");

    private double basicRate;
    private int basicMinute;
    private double additionalLineRate;
    private double ratePerExcessMinute;
    private String planName;

    private Plan(double basicRate, int basicMinute, double additionalLineRate, double ratePerExcessMinute, String planName) {
        this.basicRate = basicRate;
        this.basicMinute = basicMinute;
        this.additionalLineRate = additionalLineRate;
        this.ratePerExcessMinute = ratePerExcessMinute;
        this.planName = planName;
    }

    public double getBasicRate() {
        return basicRate;
    }
    public int getBasicMinute() {
        return basicMinute;
    }
    public double getAdditionalLineRate() {
        return additionalLineRate;
    }
    public double getRatePerExcessMinute() {
        return ratePerExcessMinute;
    }
    public  String getPlanName() {
        return planName;
    }
}

这也避免了重复的块,但可能不适合您的需要。

答案 2 :(得分:0)

我最近遇到了这个问题。尽管您已经有一个公认的解决方案(已经有4年了),但我想分享另一种方法。

我更喜欢保留这些常量,因为我觉得它更易读。一个(简单的)解决方案是重命名常量名称;)(即,给它们加上SILVER_或GOLD_前缀)。

KISS原理,并且效果很好。

public class Gold extends Plan {

private static final double GOLD_BASIC_RATE = 49.95;
private static final int GOLD_BASIC_MINUTE = 1000;
private static final double GOLD_ADDITIONAL_LINE_RATE = 14.50;
private static final double GOLD_RATE_PER_EXCESS_MINUTE = 0.45;
private static final String GOLD_PLAN_NAME = "Gold";

public double getBasicRate() {
    return GOLD_BASIC_RATE;
}

public int getBasicMinute() {
return GOLD_BASIC_MINUTE;
}

public double getAdditionalLineRate() {
    return GOLD_ADDITIONAL_LINE_RATE;
}

public double getRatePerExcessMinute() {
    return GOLD_RATE_PER_EXCESS_MINUTE;
}

public String getPlanName() {
    return GOLD_PLAN_NAME;
}