【发布时间】:2015-02-24 09:57:55
【问题描述】:
我有一个我真的不喜欢的大开关盒,但我似乎没有找到一个优雅的替代解决方案。 我们正在构建一个 JavaEE 平台,用户可以在其中创建项目。列出的方法用于确定向我们的用户显示的状态消息,这取决于许多因素,例如用户类型(我们有 2 个)、项目状态、项目的付款状态等等。这些因素中的大部分都必须以编程方式确定,最终导致了这个大型开关案例:
public List<String> getToDoMessages(Project project) {
UserAccount user = securitySession.getLoggedInAccount();
switch (user.getAccountType()) {
case EXPERT:
return getExpertToDoMessages(project, user);
case COMPANY:
return getCompanyToDoMessages(project, user);
default:
return new ArrayList<>();
}
}
private List<String> getCompanyToDoMessages(Project project, UserAccount user) {
List<String> ret = new ArrayList<>();
switch (project.getProjectState()) {
case OPEN_FOR_APPLICATION:
ret.add("projectToDo_company_applicationDeadlineNotPassed");
break;
case SELECT_APPLICATION:
ret.add("projectToDo_company_selectApplicant");
break;
case IN_PROGRESS:
ret.add("projectToDo_company_inProgress");
break;
case TEAM_PAYMENT_DISTRIBUTION:
ret.add("projectToDo_company_teamPaymentDistribution");
break;
case CONFIRM_INVOICES:
if (projectAssessmentService.hasAssessed(user, project)) {
ret.add("projectToDo_company_confirmInvoices");
} else {
ret.add("projectToDo_company_assessProject");
}
break;
default:
break;
}
return ret;
}
private List<String> getExpertToDoMessages(Project project, UserAccount user) {
ExpertPerson expert = securitySession.getExpert();
List<String> ret = new ArrayList<>();
switch (project.getProjectState()) {
case OPEN_FOR_APPLICATION:
if (projectService.hasAlreadyApplied(expert, project)) {
if (projectService.hasAlreadyAppliedAsPerson(expert, project)) {
ret.add("projectToDo_expert_appliedAsSinglePerson");
}
if (projectService.hasAlreadyAppliedAsTeam(expert, project)) {
ret.add("projectToDo_expert_appliedAsTeam");
}
} else {
if (projectService.canApply(expert, project)) {
ret.add("projectToDo_expert_openForApplication");
}
}
break;
case SELECT_APPLICATION:
ret.add("projectToDo_expert_selectApplicant");
break;
case IN_PROGRESS:
ret.add("projectToDo_expert_inProgress");
break;
case TEAM_PAYMENT_DISTRIBUTION:
Application application = project.getSelectedApplication();
if (application.isSingleApplication()) {
throw new IllegalStateException("Illegal state TEAM_PAYMENT_DISTRIBUTION for project that has selected a single application");
}
ExpertTeam team = application.getExpertTeam();
if (team.getLeader().equals(expert)) {
ret.add("projectToDo_expert_teamLeaderPaymentDistribution");
} else {
ret.add("projectToDo_expert_teamMemberPaymentDistribution");
}
break;
case CONFIRM_INVOICES:
if (projectAssessmentService.hasAssessed(user, project)) {
ret.add("projectToDo_expert_confirmInvoices");
} else {
ret.add("projectToDo_expert_assessProject");
}
break;
default:
break;
}
return ret;
}
此版本并未列出所有可能性,例如项目类型的区别仍然缺失。当然,我至少可以将语句中的代码移动到单独的方法中,但我确信必须有一个更优雅的解决方案。有谁知道在这里可能适用的好模式?
提前致谢!
【问题讨论】:
-
使用多态性代替开关
-
这在我们的情况下相当困难,我们不能将此方法移动到任何实体类中,因为我们需要依赖注入来实现某些区别。此外,这可能只会解决一个级别的 switch-case(当然总比没有好)
-
你可以编辑枚举类吗?
标签: java switch-statement refactoring