设计模式-建造者模式

今天我们要讲的是设计模式中三种模式(创建型模式、行为型模式、结构型模式)中的创建型模式中的建造者模式,也可以叫 Builder模式,在面向对象中很常用。

建造者模式的关键是将复杂对象的构建过程与它本身的表示分离开,使得同样的构建过程可以创建不同的表示。

这样说可能会有点绕,我们来看一下建造者模块对应的UML图,加深一下理解:

在这里插入图片描述
从图中我们可以看出建造者主要分为4种角色:

  • Product(产品类) :我们具体需要生成的类对象
  • Builder(抽象建造者类):为我们需要生成的类对象,构建不同的模块属性,即:公开构建产品类的属性,隐藏产品类的其他功能
  • ConcreteBuilder(具体建造者类):实现我们要生成的类对象
  • Director(导演类):确定构建我们的类对象具体有哪些模块属性,在实际应用中可以不需要这个角色,直接通过client处理

首先,我们来定义一个Product类:

public class Product {
    ArrayList<String> parts = new ArrayList<String>();

    public void add(String part) {
        parts.add(part);
    }

    public void show() {
        System.out.println(parts);
    }
}

接下来,我们定义抽象的 Builder 类:

public abstract class Builder {
public abstract void buildPart1();
public abstract void buildPart2();
public abstract Product getResult() ;
}

然后,是具体的 Builder 实现类:

public class ConcreteBuilder extends Builder {
	private Product product = new Product();
	@Override
	public void buildPart1() {
		product.add("普通产品");
	}
	@Override
	public void buildPart2() {
		product.add("高端产品");
	}
	public Product getResult() {
		return product;
	}
}

最后则是 Director 类来控制 Builder 的生产过程

public class Director {
	private Builder builder;
	public Director(Builder builder) {
		this.builder = builder;
	}
	public void construct() {
		builder.buildPart1();
		builder.buildPart2();
	}
}

测试代码

Builder builder = new ConcreteBuilder();
Director director = new Director(builder);
director.construct();
Product product = builder.getResult();
product.show();

建造者模式的应用范围很广,不但在Java源码中有,在很多第三方框架中也有实现,比如OkHttp3其中的OkHttpClient和Request也是由建造者模式实现,下面我们看一下OkHttpClient的源码:

public OkHttpClient() {
		this(new Builder());
	}
	// 由builder配置分发器、代理、协议以及自定义拦截器等
	OkHttpClient(Builder builder) {
		this.dispatcher = builder.dispatcher;
		this.proxy = builder.proxy;
		this.protocols = builder.protocols;
       //省略大段代码
		boolean isTLS = false;
		for (ConnectionSpec spec : connectionSpecs) {
			isTLS = isTLS || spec.isTls();
		}
      //省略部分代码
		if (interceptors.contains(null)) {
			throw new IllegalStateException("Null interceptor: " + interceptors);
		}
		if (
			networkInterceptors.contains(null)) {
			throw new IllegalStateException("Null network interceptor: " + networkInterceptors);
		}
	}
	public static final class Builder {
		public Builder() {
       // 分发器、协议、代理的默认参数
			dispatcher = new Dispatcher();
			protocols = DEFAULT_PROTOCOLS;
			proxySelector = ProxySelector.getDefault();
			if (proxySelector == null) {
				proxySelector = new NullProxySelector();
			}
		}
		Builder(OkHttpClient okHttpClient) {
       // 反向配置分发器、代理、协议
			this.dispatcher = okHttpClient.dispatcher;
			this.proxy = okHttpClient.proxy;
			this.protocols = okHttpClient.protocols;
        // 新增所有自定义拦截器和自定义网络拦截器
			this.interceptors.addAll(okHttpClient.interceptors);
			this
				.networkInterceptors.addAll(okHttpClient.networkInterceptors);
		}
		// 配置代理
		public Builder proxy(@Nullable Proxy proxy) {
			this.proxy = proxy;
			return this;
		}
		// 向拦截器链中增加自定义拦截器
		public Builder addInterceptor(Interceptor interceptor) {
			if (interceptor == null) throw new IllegalArgumentException("interceptor == null");
			interceptors.add(interceptor);
			return this;
		}
		// 最后是build()方法,生成OkHttpClient对象
		public OkHttpClient build() {
			return new OkHttpClient(this);
		}
	}

在Java源码里,建造者模式最典型的体现就是StringBuilder。

  • StringBuilder是一个指挥者同时是一个具体建造者
  • AbstractStringBuilder是Appendable的一个是实现类,为具体建造者
  • Appendable接口定义了append()方法,是抽象建造者

源码分析:

创建StringBuilder对象时传入字符串,传入的字符串就相当于指定产品类型,需要构建什么样的产品对象
在这里插入图片描述
进入到super.append()中,AbstractStringBuilder实现了Appendable,他是具体的建造者,在这里完成了一个具体的操作

在这里插入图片描述
Appendable定义了多个append接口,由他的实现类去实现,方便后续的可扩展性
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值