折腾Java设计模式之建造者模式
博文原址:折腾Java设计模式之建造者模式
建造者模式
Separate the construction of a complex object from its representation, allowing the same construction process to create various representations.
将复杂对象的构造与其表现分离,允许相同的构造过程用来创建不同的表现。通俗点就是,一个对象创建过程很复杂,我们将其每项元素创建过程抽离出来,通过相同的构造过程可以构造出不用的对象。还不懂可以看到如下的UML图。
建造者模式UML图
此AbstractPersonBuilder
就是如上的相同的构造,而不同的表现就是此处的PersonOneBuilder
和PersonTwoBuilder
两个相同方式的构造器,但是具体的实现是不一样而构造出不同的表现。所以就是相同的构造过程而构造出不同的对象。
建造者模式角色
抽象建造者(AbstractPersonBuilder
或者Builder
):抽象类或者接口,复杂对象的属性的抽象方法,并不涉及具体的对象部件的创建;
具体建造者(PersonOneBuilder
和PersonTwoBuilder
):实现抽象建造者,针对不同的业务,具体化复杂对象的各部分的创建。 在建造过程完成后,提供产品的实例;
指挥者(Director
):调用具体建造者来创建复杂对象的各个部分,在指导者中不涉及具体产品的信息,只负责保证对象各部分完整创建或按某种顺序创建;
具体的产品(Person
):需创建的复杂对象;
建造者模式源码干货
源码地址:请点击我
在这里我分为三种情况讲讲建造者模式,第一种是我们最原始的建造者模式来构建,第二种是我们在实体对象时会使用的,第三种是我们平常对实体对象最常规使用方法借助lombok。
第一种建造者模式
使用的真是上面按照角色来建造的方式,稍微比如下的两种方法负责点。
抽象建造者
public abstract class AbstractPersonBuilder {
protected Person product = new Person();
public abstract void buildName();
public abstract void buildAge();
public abstract void buildChildren();
public Person build() {
return product;
}
}
第一个具体建造者
public class PersonOneBuilder extends AbstractPersonBuilder {
public void buildName() {
product.setName("老one");
}
public void buildAge() {
product.setAge(44);
}
public void buildChildren() {
product.setChildren(Lists.newArrayList("小one"));
}
}
第二个具体建造者
public class PersonTwoBuilder extends AbstractPersonBuilder {
public void buildName() {
product.setName("老two");
}
public void buildAge() {
product.setAge(55);
}
public void buildChildren() {
product.setChildren(Lists.newArrayList("小two"));
}
}
Person类充当产品数据
public class Person {
private String name;
private int age;
private List<String> children;
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", children=" + children +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public List<String> getChildren() {
return children;
}
public void setChildren(List<String> children) {
this.children = children;
}
}
指挥者,指定具体的建造者用来建造对象
public class Director {
private AbstractPersonBuilder builder;
public Director(AbstractPersonBuilder builder) {
this.builder = builder;
}
public void setBuilder(AbstractPersonBuilder builder) {
this.builder = builder;
}
public Person construct() {
builder.buildName();
builder.buildAge();
builder.buildChildren();
return builder.build();
}
}
示例
@Slf4j
public class Application {
public static void main(String[] args) {
Director director = new Director(new PersonOneBuilder());
Person person = director.construct();
log.info("person的信息:{}", person);
director.setBuilder(new PersonTwoBuilder());
person = director.construct();
log.info("person的信息:{}", person);
}
}
结果:
第二种建造者模式
第二种方式比上面那种简单些,因为我们只指定了一种构造方式,并且还可以借用第三方工具IDEA+Plugins。
在IDEA中可以搜索
使用方法:
1.找到对应需要添加bulid的类通过自动生成快捷键可以查看到build
2.根据自己的风格可以定义bulid的名字,各个bulid方法的前缀以及包名,具体bulider如下代码中。
PersonBuilder用来Person的构建者
public final class PersonBuilder {
private String name;
private int age;
private List<String> children;
private PersonBuilder() {
}
public static PersonBuilder builder() {
return new PersonBuilder();
}
public PersonBuilder withName(String name) {
this.name = name;
return this;
}
public PersonBuilder withAge(int age) {
this.age = age;
return this;
}
public PersonBuilder withChildren(List<String> children) {
this.children = children;
return this;
}
public Person build() {
Person person = new Person();
person.setName(name);
person.setAge(age);
person.setChildren(children);
return person;
}
}
Person类充当产品数据
public class Person {
private String name;
private int age;
private List<String> children;
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", children=" + children +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public List<String> getChildren() {
return children;
}
public void setChildren(List<String> children) {
this.children = children;
}
}
示例
@Slf4j
public class Application {
public static void main(String[] args) {
Person wang = PersonBuilder.builder()
.withAge(40)
.withName("老王")
.withChildren(Lists.newArrayList("李一一", "吴老三"))
.build();
log.info("老王的信息:{}", wang);
}
}
结果如下:
第三种建造者模式
第三种模式相对来说就简单非常多,因为我们借用的是lombok的@Builder注解。lombok在18.2版本中引入了@SuperBulider注解用来解决@Builder类的继承不生效的问题。详细的使用阔以看我上篇文章 折腾Java设计模式之模板方法模式
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Person {
private String name;
private int age;
private List<String> children;
}
@Slf4j
public class Application {
public static void main(String[] args) {
Person wang = Person.builder()
.age(40)
.name("老王")
.children(Lists.newArrayList("李一一", "吴老三"))
.build();
log.info("老王的信息:{}", wang);
}
}
结果:
总结
第二、三种模式在我们经常操作像对VO、DO、DTO对象时,常用如此定义。第一种标准的建造者模式,其实本身指挥者这个角色是不关心具体的产品实现的,相对于是一种解耦,对于如果新增一种建造者实现,可以方便扩展,符合开闭原则,但是无独有偶,实现了上述优点后,但是缺点也跟着来,新增了很多类,维护成本高,如果建造者内部发生变更,就不太适合建造者这种模式了。总体而言还是有很多使用场景的。像StringBulider其实也是一种。像之前在spring-boot的spring-cache中的扩展redis缓存的ttl和key名这篇文章中定义的RedisCacheManagerBuilder,以及我们常用的以后要讲的Feign的Builder等等。
欢迎关注
折腾Java设计模式之建造者模式的更多相关文章
- 折腾Java设计模式之备忘录模式
原文地址:折腾Java设计模式之备忘录模式 备忘录模式 Without violating encapsulation, capture and externalize an object's int ...
- 折腾Java设计模式之状态模式
原文地址 折腾Java设计模式之状态模式 状态模式 在状态模式(State Pattern)中,类的行为是基于它的状态改变的.这种类型的设计模式属于行为型模式.在状态模式中,我们创建表示各种状态的对象 ...
- 折腾Java设计模式之模板方法模式
博客原文地址:折腾Java设计模式之模板方法模式 模板方法模式 Define the skeleton of an algorithm in an operation, deferring some ...
- 折腾Java设计模式之访问者模式
博客原文地址:折腾Java设计模式之访问者模式 访问者模式 Represent an operation to be performed on the elements of an object st ...
- 折腾Java设计模式之命令模式
博客原文地址 折腾Java设计模式之命令模式 命令模式 wiki上的描述 Encapsulate a request as an object, thereby allowing for the pa ...
- Java 设计模式之建造者模式(四)
原文地址:Java 设计模式之建造者模式(四) 博客地址:http://www.extlight.com 一.前言 今天继续介绍 Java 设计模式中的创建型模式--建造者模式.上篇设计模式的主题为 ...
- java设计模式3——建造者模式
java设计模式3--建造者模式 1.建造者模式介绍: 建造者模式属于创建型模式,他提供了一种创建对象得最佳方式 定义: 将一个复杂对象的构建和与它的表示分离,使得同样的构建过程可以创建不同的表示 主 ...
- Java设计模式之建造者模式(Builder)
前言: 最近一直在学习okHttp,也对其做了一些整理,okHttp和Retrofit结合大大加速我们的开发效率,源码里面采用了很多设计模式,今天我们来学习一下其中的设计模式之一建造者模式. 建造者模 ...
- Java设计模式之三 ----- 建造者模式和原型模式
前言 在上一篇中我们学习了工厂模式,介绍了简单工厂模式.工厂方法和抽象工厂模式.本篇则介绍设计模式中属于创建型模式的建造者模式和原型模式. 建造者模式 简介 建造者模式是属于创建型模式.建造者模式使用 ...
随机推荐
- 响应式编程知多少 | Rx.NET 了解下
1. 引言 An API for asynchronous programming with observable streams. ReactiveX is a combination of the ...
- 聊一聊快速排序(Js)
快速排序 基本思路 双指针+递归分治(本质是一个创建二叉树搜索树的过程) 通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据 ...
- 关于MQ,你必须知道的
我走过最长的路是你的套路 女:二号男嘉宾,假如我们牵手成功后,你会买名牌包包给我吗? 男:那你会听话吗? 女:会 听话. 男:听话 咱不买! OK那么消息队列MQ有什么套路呢?(这个话题转换生硬度连我 ...
- Java集合详解7:HashSet,TreeSet与LinkedHashSet
今天我们来探索一下HashSet,TreeSet与LinkedHashSet的基本原理与源码实现,由于这三个set都是基于之前文章的三个map进行实现的,所以推荐大家先看一下前面有关map的文章,结合 ...
- PHP扩展高性能日志系统SeasLog简单上手
Windows部分:-------------------------------------------------------- https://pecl.php.net/package/Seas ...
- 微信小程序 组件通信相关知识整理
1.自定义组件间通信与事件 https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/events.htm ...
- Android Gradle defaultConfig详解及实用技巧
实际项目中,都会应用Android Gradle Plugin,根据实际中的项目模块的职责,可以具体应用如下四种插件类型. 1,apply plugin: 'com.android.applicati ...
- PageHelper分页异常(java.base/java.util.ArrayList cannot be cast to com.github.pagehelper.Page)
在SqlMapConfig.xml里面配置分页插件 applicationContext-service.xml里面的配置,我出现问题谁因为,在salSessionFactory里没注入全局配置文件
- [目录]搭建一个简单的WebGIS应用程序
“如果一件事情超过自己的能力,自己很难达到,那就像是婴儿跳高,不但没有好处,反而拔苗助长”. 4月份时报名参加了2018年ESRI杯GIS应用开发比赛,到前几天提交了作品.作品很简单,没有那么多复杂深 ...
- Android-----Intent中通过startActivity(Intent intent )显式启动新的Activity
Intent:即意图,一般是用来启动新的Activity,按照启动方式分为两类:显式Intent 和 隐式Intent 显示Intent就是直接以“类名称”来指定要启动哪一个Activity:Inte ...