在指挥者类中可以注入一个抽象建造者类型的对象,其核心在于提供了一个建造方法construct(),在该方法中调用了builder对象的构造部件的方法,最后返回一个产品对象。
对于客户端而言,只需关心具体的建造者即可,代码片段如下所示:
public static void main(String[] args) { Builder builder = new ConcreteBuilder(); Director director = new Director(builder); Product product = director.construct(); } 模式简化在有些情况下,为了简化系统结构,可以将Director和抽象建造者Builder进行合并,在Builder中提供逐步构建复杂产品对象的construct()方法。
public abstract class Builder { // 创建产品对象 protected Product product = new Product(); public abstract void buildPartA(); public abstract void buildPartB(); public abstract void buildPartC(); // 返回产品对象 public Product construct() { buildPartA(); buildPartB(); buildPartC(); return product; } } 模式应用 模式在JDK中的应用java.util.stream.Stream.Builder
public interface Builder<T> extends Consumer<T> { /** * Adds an element to the stream being built. */ default Builder<T> add(T t) { accept(t); return this; } /** * Builds the stream, transitioning this builder to the built state */ Stream<T> build(); } 模式在开源项目中的应用看下Spring是如何构建org.springframework.web.servlet.mvc.method.RequestMappingInfo
/** * Defines a builder for creating a RequestMappingInfo. * @since 4.2 */ public interface Builder { /** * Set the path patterns. */ Builder paths(String... paths); /** * Set the request method conditions. */ Builder methods(RequestMethod... methods); /** * Set the request param conditions. */ Builder params(String... params); /** * Set the header conditions. * <p>By default this is not set. */ Builder headers(String... headers); /** * Build the RequestMappingInfo. */ RequestMappingInfo build(); }Builder接口的默认实现,如下:
private static class DefaultBuilder implements Builder { private String[] paths = new String[0]; private RequestMethod[] methods = new RequestMethod[0]; private String[] params = new String[0]; private String[] headers = new String[0]; public DefaultBuilder(String... paths) { this.paths = paths; } @Override public Builder paths(String... paths) { this.paths = paths; return this; } @Override public DefaultBuilder methods(RequestMethod... methods) { this.methods = methods; return this; } @Override public DefaultBuilder params(String... params) { this.params = params; return this; } @Override public DefaultBuilder headers(String... headers) { this.headers = headers; return this; } @Override public RequestMappingInfo build() { ContentNegotiationManager manager = this.options.getContentNegotiationManager(); PatternsRequestCondition patternsCondition = new PatternsRequestCondition( this.paths, this.options.getUrlPathHelper(), this.options.getPathMatcher(), this.options.useSuffixPatternMatch(), this.options.useTrailingSlashMatch(), this.options.getFileExtensions()); return new RequestMappingInfo(this.mappingName, patternsCondition, new RequestMethodsRequestCondition(this.methods), new ParamsRequestCondition(this.params), new HeadersRequestCondition(this.headers), new ConsumesRequestCondition(this.consumes, this.headers), new ProducesRequestCondition(this.produces, this.headers, manager), this.customCondition); } }Spring框架中许多构建类的实例化使用了类似上面方式,总结有以下特点:
Builder大多是构建类的内部类,构建类提供了一个静态创建Builder的方法
Builder返回构建类的实例,大多通过build()方法
构建过程有大量参数,除了几个必要参数,用户可根据自己所需选择设置其他参数实例化对象
模式总结建造者模式的核心在于如何一步步构建一个包含多个组成部件的完整对象,使用相同的构建过程构建不同的产品,在软件开发中,如果我们需要创建复杂对象并希望系统具备很好的灵活性和可扩展性可以考虑使用建造者模式。