问题是关于这段代码 (在安卓应用程序中):
private Task<QuerySnapshot> getVotesFromDB() {
res = new int[]{0, 0, 0}; // a private class-member
return FirebaseFirestore.getInstance().collection("Votes")
.whereEqualTo("proposition_key", curr_proposition.getKey())
.get().addOnCompleteListener(task -> {
if (task.isSuccessful()) {
for (QueryDocumentSnapshot document : task.getResult()) {
String userChoice = (String) document.get("user_choice");
int choice;
switch (userChoice) {
case "against":
choice = 0;
break;
case "impossible":
choice = 1;
break;
case "agreement":
choice = 2;
break;
default:
throw new IllegalStateException("Unexpected value: " + userChoice);
}
res[choice]++;
}
}
});
}通常,代码从Firestore集合中读取一些行,并对它们应用一些“业务逻辑”(计算每种类型的字符串数)。未来,业务逻辑可能会变得比单纯的计算要复杂得多。因此,我正在寻找一种重构代码的方法,以便业务逻辑可以与数据库分开编写和测试。我想要的是具有某种形式的功能:
int[] countVotes(Generator<String> strings) {
res = new int[3];
(for String userChoice: strings) {
// Update res as above
}
return res;
}可以进行单元测试,而不需要任何数据库连接。然后,对上述功能进行如下重构:
private Generator<String> getVotesFromDB() {
return FirebaseFirestore.getInstance().collection("Votes")
.whereEqualTo("proposition_key", curr_proposition.getKey())
.get().addOnCompleteListener(task -> {
if (task.isSuccessful()) {
for (QueryDocumentSnapshot document : task.getResult()) {
userChoice = (String) document.get("user_choice");
yield userChoice;
}
}
});
}运行如下:
countVotes(getVotesFromDB())问题是,我不知道如何使用异步函数调用来完成这个任务。是否有方法以类似或更好的方式重构代码?
发布于 2021-12-30 16:23:19
您可以将结果收集到数组中,然后使用单独的方法处理该结果。然后,如果处理方法是复杂的,则可以对各种不同的结果列表进行单元测试。
private void getVotesFromDB() {
FirebaseFirestore.getInstance().collection("Votes")
.whereEqualTo("proposition_key", curr_proposition.getKey())
.get().addOnCompleteListener(task -> {
if (task.isSuccessful()) {
ArrayList<String> results = new ArrayList();
for (QueryDocumentSnapshot document : task.getResult()) {
String userChoice = (String) document.get("user_choice");
results.add(userChoice);
}
// assign the result to a class member
res = countVotes(results);
// do something to signal to the rest of the code
// that results have been processed (e.g. post to
// LiveData or call another "showResults" method)
}
});
}然后,任何复杂的计数逻辑都可以独立于防火墙调用。
int[] countVotes(ArrayList<String> choices) {
int[] res = new int[]{0,0,0};
// count the votes
return res;
}https://stackoverflow.com/questions/70533401
复制相似问题