design-patterns - 传递部分完整的构建器实例
问题描述
将构建器实例从一个对象传递到另一个对象以添加不同的字段值是否可以接受?
在下面的示例中,应从多个位置(DateAdder 和 PlaceAdder)获取创建 VacationPlan 实例的详细信息。Organizer 创建构建器实例并将其作为参数传递给这些“appender”实例,最后执行 build() 调用。
例子:
public class Organizer {
private final DateAdder dateAdder;
private final PlaceAdder placeAdder;
private final VacationProviderSearch vacationProviderSearch;
public void organizeVacation() {
VacationPlan.Builder vacationPlanBuilder = VacationPlan.newBuilder();
vacationPlanBuilder = dateAdder.addDate(vacationPlanBuilder);
vacationPlanBuilder = placeAdder.addPlace(vacationPlanBuilder);
VacationPlan vacationPlan = vacationPlanBuilder.build();
List<Provider> providers = vacationProviderSearch.getProviders(vacationPlan);
// use providers to get the best vacation provider
}
}
我们在工作中讨论了这种方法,我认为这些单独的附加程序最好接受非构建器实例作为参数并将它们各自的输出作为 POJO 返回。
如下所示:
public void organizeVacation() {
VacationDateRange dateRange = dateProvider.getDateRange(userRequestJson);
String location = locationProvider.getLocation(userRequestJson);
VacationPlan vacationPlan = vacationPlanBuilder.newBuilder()
.startDate(dateRange.getStartDate())
.endDate(dateRange.getEndDate())
.location(location)
.build();
List<Provider> providers = vacationProviderSearch.getProviders(vacationPlan);
// use providers to get the best vacation provider
}
这可以确保系统中没有浮动的可变实例。这些方法中哪个更好?
解决方案
第二种方法更简洁,因为它消除了日期/位置提供程序与构建器或 VacationPlan 类型的不必要耦合。它还使得对提供者进行单元测试变得更容易(在第一种方法中进行测试需要在构建器上公开 getter 或模拟构建器,这两种方法都不是可取的)。
推荐阅读
- react-native - 如何减少反应原生应用程序的启动时间
- javascript - 我的 switch 条件语句将如何正常工作?
- linux - SH:将 awk 命令输出保存在变量中
- javascript - 如何让等待javascript在返回结果之前完成所有功能
- reactjs - Next.js 部署到 Heroku 的第一个项目,开始脚本崩溃?
- google-bigquery - 从 Bigquery Storage API (python) 读取时,如何获得“已处理的字节数”和“已计费的字节数”
- c++ - 标头中的概念不限制 C++20 中的参数包?
- webgl - WebGL m3 对象?
- java - 当您尝试迭代的数组列表太大时,您可以获得 IndexOutOfBoundException 吗?还是我的循环有问题?
- unity3d - Unity 对撞机以一种奇怪且出乎意料的方式运行。如何解决?