【发布时间】: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 个变量?
-
您可以创建一个方法来完成所有这些工作,并接受它所设置的任何内容的 consumer 和
responseCounts。然后你用你在里面做的事情的 lambda 调用那个方法。 -
感谢 RealSkeptic,您能否详细说明一下或指出一个示例?我的 Java 8 不是最好的。
标签: java java-8 coding-style refactoring code-duplication