【问题标题】:How best to refactor variable instantiation duplication in Java?如何最好地重构 Java 中的变量实例化重复?
【发布时间】:2023-04-01 08:49:01
【问题描述】:

我在 Java 中有两种收集不同信息的方法,但它们都设置和运行相同的过程,然后我们从中收集信息 - 数据的收集发生在一个循环中,并且我们实例化的变量也被使用在循环。

 Map<Integer, Integer> getResponsesWithCount(int baseCostMultiplier, int reels, int visibleSymbols, String stakeCostUuid, int totalBets) throws InsufficientFundsException {
    final int stake = getStake(baseCostMultiplier, stakeCostUuid);
    long balance = 10L * stake;
    final TestGpasPlatform testGpasPlatform = TestGpasPlatform.create(ryotaAdapter, TestGpasPlatform.DEFAULT_MIN_BET, Math.max(stake, TestGpasPlatform.DEFAULT_MAX_BET), TestGpasPlatform.DEFAULT_MAX_WIN, ImmutableList.of(baseCostMultiplier));

    final Map<Integer, Integer> responseCounts = new HashMap<>();
    for (int count = 0; count < totalBets; count++) {
        final Tuple2<List<Output>, TestGpasPlatform> result = playWithRealRng(baseCostMultiplier, count, reels, visibleSymbols, stakeCostUuid, testGpasPlatform);
        // If we run out of balance, re-start, we want to do meaningful spins that trigger features, etc
        balance = checkBalance(stake, balance, result._1(), count);
        final int byteLength = result._2.getLastResponse().map(s -> s.getBytes().length).orElse(0);
        responseCounts.putIfAbsent(byteLength, 0);
        responseCounts.put(byteLength, responseCounts.get(byteLength) + 1);
    }
    return responseCounts;
}

Map<Integer, Integer> getResponsesWithPayouts(int baseCostMultiplier, int reels, int visibleSymbols, String stakeCostUuid, int totalBets) throws InsufficientFundsException{
    final int stake = getStake(baseCostMultiplier, stakeCostUuid);
    long balance = 10L * stake;
    final TestGpasPlatform testGpasPlatform = TestGpasPlatform.create(ryotaAdapter, TestGpasPlatform.DEFAULT_MIN_BET, Math.max(stake, TestGpasPlatform.DEFAULT_MAX_BET), TestGpasPlatform.DEFAULT_MAX_WIN, ImmutableList.of(baseCostMultiplier));
    final Map<Integer, Integer> responseCounts = new HashMap<>();
    for (int count = 0; count < totalBets; count++) {
        final Tuple2<List<Output>, TestGpasPlatform> result = playWithRealRng(baseCostMultiplier, count, reels, visibleSymbols, stakeCostUuid, testGpasPlatform);

        // If we run out of balance, re-start, we want to do meaningful spins that trigger features, etc
        balance = checkBalance(stake, balance, result._1(), count);

        final int byteLength = result._2.getLastResponse().map(s -> s.getBytes().length).orElse(0);
        final PlayData playData = result._2.getLastResponse().map(s -> new Gson().fromJson(s, GdkPlayData.class)).orElse(new GdkPlayData());
        final java.util.List<SlotsActionData> actionData = playData.findLastPlay().getLastPlayInModeData().getSlotsData().getActions();
        final int sumOfPayouts = actionData.stream()
                                           .map(SlotsActionData::getPayouts)
                                           .mapToInt(java.util.List::size)
                                           .sum();
        responseCounts.putIfAbsent(byteLength, sumOfPayouts);
    }
    return responseCounts;
}

每个方法的前 6 行代码都是完全重复的,但我不确定我应该如何清理它。

我认为这个问题的一个扩展是我有两个方法调用链,它们对除了收集的数据之外的所有方法都做同样的事情,而不是像我认为那样有一个布尔运算符来拆分这个功能,这很糟糕设计,我实现了一个新的方法链来完成它。我应该采取不同的做法吗?

【问题讨论】:

  • 选择重复的代码部分并根据您的 IDE 使用提取方法快捷方式。
  • 它不适用于特定的选定块。正如我在帖子中所说,它在循环之前开始并在循环内结束的事实使得重构变得困难。 IDEA 根本不提供解决方案。
  • 也许我可以创建一个对象来保存每个方法开头 4 行中的变量,并在每个方法中使用该对象,而不是两次实例化这 4 个变量?
  • 您可以创建一个方法来完成所有这些工作,并接受它所设置的任何内容的 consumerresponseCounts。然后你用你在里面做的事情的 lambda 调用那个方法。
  • 感谢 RealSkeptic,您能否详细说明一下或指出一个示例?我的 Java 8 不是最好的。

标签: java java-8 coding-style refactoring code-duplication


【解决方案1】:

您可以创建一个通用方法并传递类型,如withCount,如下所示,

Map<Integer, Integer> getResponses(int baseCostMultiplier, int reels, int visibleSymbols, String stakeCostUuid, int totalBets, boolean withCount) throws InsufficientFundsException {
    final int stake = getStake(baseCostMultiplier, stakeCostUuid);
    long balance = 10L * stake;
    final TestGpasPlatform testGpasPlatform = TestGpasPlatform.create(ryotaAdapter, TestGpasPlatform.DEFAULT_MIN_BET, Math.max(stake, TestGpasPlatform.DEFAULT_MAX_BET), TestGpasPlatform.DEFAULT_MAX_WIN, ImmutableList.of(baseCostMultiplier));

    final Map<Integer, Integer> responseCounts = new HashMap<>();
    for (int count = 0; count < totalBets; count++) {
        final Tuple2<List<Output>, TestGpasPlatform> result = playWithRealRng(baseCostMultiplier, count, reels, visibleSymbols, stakeCostUuid, testGpasPlatform);
        // If we run out of balance, re-start, we want to do meaningful spins that trigger features, etc
        balance = checkBalance(stake, balance, result._1(), count);
        final int byteLength = result._2.getLastResponse().map(s -> s.getBytes().length).orElse(0);

        if(withCount) {
            responseCounts.putIfAbsent(byteLength, 0);
            responseCounts.put(byteLength, responseCounts.get(byteLength) + 1);
        }else{
            final PlayData playData = result._2.getLastResponse().map(s -> new Gson().fromJson(s, GdkPlayData.class)).orElse(new GdkPlayData());
            final java.util.List<SlotsActionData> actionData = playData.findLastPlay().getLastPlayInModeData().getSlotsData().getActions();
            final int sumOfPayouts = actionData.stream()
                    .map(SlotsActionData::getPayouts)
                    .mapToInt(java.util.List::size)
                    .sum();
            responseCounts.putIfAbsent(byteLength, sumOfPayouts);
        }
    }
    return responseCounts;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-12-24
    • 1970-01-01
    • 2020-07-04
    • 1970-01-01
    • 1970-01-01
    • 2016-02-02
    • 2023-03-17
    • 1970-01-01
    相关资源
    最近更新 更多