Builder模式

摘要:日常写代码有时候会遇到bean有很多的参数,也即是有多个构造器参数,这个时候我们可以考虑使用构建器。它既能保证像重叠构造器模式那样的安全性,也能保证像JavaBean模式那么好的可读性。这就是Builder模式。

正文:

讲Builder模式之前,我们先来看一下日常使用构造器的方法:

package com.bean.builder;public class Bean { private int a; private int b; private int c; private int d; private int e; private int f; public Bean(int a, int b, int c, int d, int e, int f) { super(); this.a = a; this.b = b; this.c = c; this.d = d; this.e = e; this.f = f; } public Bean(int a, int b, int c, int d, int e) { super(); this.a = a; this.b = b; this.c = c; this.d = d; this.e = e; } public Bean(int a, int b, int c, int d) { super(); this.a = a; this.b = b; this.c = c; this.d = d; } // ....构造方法 public Bean() { super(); } //省略setter getter方法}

由此可见,若想要灵活的new一个对象需要创建很多个重载的构造器,可读性和可维护性都不是很高。

使用构建器示例:

package com.bean.builder;public class BuilderBean { private final int a; private final int b; private final int c; private final int d; private final int e; private final int f; public static class Builder{ private final int a; private final int b; private int c = 0; private int d = 0; private int e = 0; private int f = 0; public Builder(int a,int b){ this.a = a; this.b = b; } public Builder c(int val){ c = val; return this; } public Builder d(int val){ d = val; return this; } public Builder e(int val){ e = val; return this; } public Builder f(int val){ f = val; return this; } public BuilderBean build(){ return new BuilderBean(this); } } private BuilderBean(Builder builder){ a = builder.a; b = builder.b; c = builder.c; d = builder.d; e = builder.e; f = builder.f; } }

注意BuilderBean是不可变的,所有的默认参数值都单独放一个地方。builder的setter方法返回builder本身,以便后续继续调用别的方法。下面是客户端的代码

BuilderBean bb = new BuilderBean.Builder(10, 20). c(3).e(5).f(6).build();

这样的客户端代码很容易编写,更重要的是易于阅读。与构造器相比,builder的微略优势在于,builder可以有多个可变的参数,构造器就像方法一样,只能有一个可变参数。

Builder模式的优点:

1.使用Builder模式必然会导致写两遍相关属性的代码和setter方法,看起来有点吃力不讨好。然而需要看到的是,客户端代码的可用性和可读性得到了大大提高。与此同时,构造函数的参数数量明显减少调用起来非常直观。

2.Builder模式十分灵活,可以利用单个builder构建多个对象,还可在创建期间进行调整根据对象的不同进行改变。

Builder模式的缺点:

1.为了创建对象,必须先创建它的构建器。虽然创建器的开销在实践中可能不那么明显,但是在某些十分注重性能的情况下,可能就成问题了。

2.Builder模式还比重叠构造器模式更加冗长,最好在4个或4个以上的参数才使用。

在我的Builder实现中,我会用Builder的构造函数而不是set方法传递客户需要的属性。这样做的好处在于,对象总是能被一次完整的实例化,而不是靠开发人员调用时用set方法补充额外的属性完成实例化。这也体现了不可变性带来的好处。然而,相应地也会造成自己设定的属性方法可读性降低。

总结: 如果类的构造器或者静态工厂中具有多个参数,设计这种类时,Builder是种不错的选择,特别是当大多数参数都是可选的时候。与使用传统的重叠构造器模式相比,使用Builder模式的客户端代码更易于编写和阅读,构建器也比JavaBean更加安全。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏chenssy

【死磕 Spring】----- IOC 之 Spring 统一资源加载策略

在学 Java SE 的时候我们学习了一个标准类 java.net.URL,该类在 Java SE 中的定位为统一资源定位器(Uniform Resource ...

1653
来自专栏求索之路

Android源码设计模式解析与实战笔记

1.单一职责原则:比如说一个ImageLoader,需要加载图片的缓存图片,此时如果将这两个功能都放在一个类中,就违反了这个原则, 我们需要将不同的功能用类精...

4645
来自专栏JackieZheng

照虎画猫写自己的Spring——依赖注入

前言 上篇《照虎画猫写自己的Spring》从无到有讲述并实现了下面几点 声明配置文件,用于声明需要加载使用的类 加载配置文件,读取配置文件 解析配置文件,需要将...

2038
来自专栏Flutter入门到实战

模仿安卓源码,手写过时的方法兼容低版本

我们经常会使用getColor(R.color.XXX)获取颜色的资源文件,但是在安卓6.0开始,这个方法被标注为过时,推荐使用两个参数的方法替代,如下图所示:

1032
来自专栏移动开发的那些事儿

Android开发之逻辑单元测试

以上createInetSocketAddress方法就是我在编写单元测试的时候单独抽离出来的方法,一方面我需要mock一个InetSocketAddress来...

1141
来自专栏我就是马云飞

Architecture Components ViewModel的控制。

前言 作为MVVM 系列的第二篇,我们来看一下之前提出的第二个问题,就是ViewModel是如果控制生命周期的,并且保证在一定范围内的唯一性。 ViewMode...

1709
来自专栏Java呓语

DataBinding·常用注解说明

Observable接口提供给开发者添加/移除监听者的机制。为了使开发更便捷,我们创建了BaseObservable类,它已经实现了Observable接口中的...

1414
来自专栏developerHaoz 的安卓之旅

Android 关于内存泄露,你必须了解的东西

内存管理的目的就是让我们在开发过程中有效避免我们的应用程序出现内存泄露的问题。内存泄露相信大家都不陌生,我们可以这样理解:「没有用的对象无法回收的现象就是内存泄...

731
来自专栏Android开发指南

13.缓存、三级缓存、内存溢出、AsyncTask

44312
来自专栏清晨我上码

spring boot 使用ReloadableResourceBundleMessageSource的坑

所以我们重点关注的AbstractMessageSource的getMessage方法。以其中一个为例分析

4922

扫码关注云+社区

领取腾讯云代金券