首页 > 解决方案 > 传递部分完整的构建器实例

问题描述

将构建器实例从一个对象传递到另一个对象以添加不同的字段值是否可以接受?

在下面的示例中,应从多个位置(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
}

这可以确保系统中没有浮动的可变实例。这些方法中哪个更好?

标签: design-patternsbuilder

解决方案


第二种方法更简洁,因为它消除了日期/位置提供程序与构建器或 VacationPlan 类型的不必要耦合。它还使得对提供者进行单元测试变得更容易(在第一种方法中进行测试需要在构建器上公开 getter 或模拟构建器,这两种方法都不是可取的)。


推荐阅读