博文原址:折腾Java设计模式之建造者模式

建造者模式

Separate the construction of a complex object from its representation, allowing the same construction process to create various representations.

将复杂对象的构造与其表现分离,允许相同的构造过程用来创建不同的表现。通俗点就是,一个对象创建过程很复杂,我们将其每项元素创建过程抽离出来,通过相同的构造过程可以构造出不用的对象。还不懂可以看到如下的UML图。

建造者模式UML图

AbstractPersonBuilder就是如上的相同的构造,而不同的表现就是此处的PersonOneBuilderPersonTwoBuilder两个相同方式的构造器,但是具体的实现是不一样而构造出不同的表现。所以就是相同的构造过程而构造出不同的对象。

建造者模式角色

抽象建造者(AbstractPersonBuilder或者Builder):抽象类或者接口,复杂对象的属性的抽象方法,并不涉及具体的对象部件的创建;

具体建造者(PersonOneBuilderPersonTwoBuilder):实现抽象建造者,针对不同的业务,具体化复杂对象的各部分的创建。 在建造过程完成后,提供产品的实例;

指挥者(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设计模式之建造者模式的更多相关文章

  1. 折腾Java设计模式之备忘录模式

    原文地址:折腾Java设计模式之备忘录模式 备忘录模式 Without violating encapsulation, capture and externalize an object's int ...

  2. 折腾Java设计模式之状态模式

    原文地址 折腾Java设计模式之状态模式 状态模式 在状态模式(State Pattern)中,类的行为是基于它的状态改变的.这种类型的设计模式属于行为型模式.在状态模式中,我们创建表示各种状态的对象 ...

  3. 折腾Java设计模式之模板方法模式

    博客原文地址:折腾Java设计模式之模板方法模式 模板方法模式 Define the skeleton of an algorithm in an operation, deferring some ...

  4. 折腾Java设计模式之访问者模式

    博客原文地址:折腾Java设计模式之访问者模式 访问者模式 Represent an operation to be performed on the elements of an object st ...

  5. 折腾Java设计模式之命令模式

    博客原文地址 折腾Java设计模式之命令模式 命令模式 wiki上的描述 Encapsulate a request as an object, thereby allowing for the pa ...

  6. Java 设计模式之建造者模式(四)

    原文地址:Java 设计模式之建造者模式(四) 博客地址:http://www.extlight.com 一.前言 今天继续介绍 Java 设计模式中的创建型模式--建造者模式.上篇设计模式的主题为 ...

  7. java设计模式3——建造者模式

    java设计模式3--建造者模式 1.建造者模式介绍: 建造者模式属于创建型模式,他提供了一种创建对象得最佳方式 定义: 将一个复杂对象的构建和与它的表示分离,使得同样的构建过程可以创建不同的表示 主 ...

  8. Java设计模式之建造者模式(Builder)

    前言: 最近一直在学习okHttp,也对其做了一些整理,okHttp和Retrofit结合大大加速我们的开发效率,源码里面采用了很多设计模式,今天我们来学习一下其中的设计模式之一建造者模式. 建造者模 ...

  9. Java设计模式之三 ----- 建造者模式和原型模式

    前言 在上一篇中我们学习了工厂模式,介绍了简单工厂模式.工厂方法和抽象工厂模式.本篇则介绍设计模式中属于创建型模式的建造者模式和原型模式. 建造者模式 简介 建造者模式是属于创建型模式.建造者模式使用 ...

随机推荐

  1. 目标检测之YOLO V1

    前面介绍的R-CNN系的目标检测采用的思路是:首先在图像上提取一系列的候选区域,然后将候选区域输入到网络中修正候选区域的边框以定位目标,对候选区域进行分类以识别.虽然,在Faster R-CNN中利用 ...

  2. 【STM32H7教程】第11章 STM32H7移植SEGGER的硬件异常分析

    完整教程下载地址:http://forum.armfly.com/forum.php?mod=viewthread&tid=86980 第11章       STM32H7移植SEGGER的硬 ...

  3. 02 JVM 从入门到实战 | 什么样的对象需要被 GC

    引言 上一篇文章 JVM 基本介绍 我们了解了一些基本的 JVM 知识,本篇开始逐步学习垃圾回收,我们都知道既然叫垃圾回收,那回收的就应该是垃圾,可是我们怎么知道哪些对象是垃圾呢? 哪些对象需要被回收 ...

  4. C#相等性 - “==”

    今天写一下C#里的“==”这个操作符. 原始类型 假象 在刚学C#的时候,我以为C#里的==和.NET里的object.Equals()方法是一样的,就是一个语法糖而已.其实它们的底层机制是不一样的, ...

  5. 实现AutoMapper(1.0版本)

    最近有个需求就是实体之间自动转换,网上肯定有很多现成的实现,不过还是自己写了一个,就当对java高级特性的一个熟悉的过程.这中间包含了泛型,反射,lamada表达式.对于想了解java高级特性的人来说 ...

  6. ABP项目依赖图,根据自已生在的Demo项目分析而得

    根据自已生在的Demo项目分析而得 在线学习代码库:https://github.com/AtwindYu/ABPStudy

  7. Elasticsearch安装配置

    文档地址: https://www.elastic.co/guide/en/elasticsearch/reference/6.5/setup.html 官方页面提供自0.9版本以来的说明文档,由于我 ...

  8. 「工具」Aquarelo - 来自意大利的色阶管理工具

    Aquarelo是一款小而美的色阶管理工具,由意大利团队开发,包含三个核心功能,可用于色彩管理.色彩搭配等场景. ## 相关参数 * 操作系统:macOS* 工具官网:[Aquarelo for Ma ...

  9. Ambari:Provide ability to apply single patches on top of RU release

    https://issues.apache.org/jira/browse/AMBARI-12556 Provide ability to apply single patches on top of ...

  10. 以Windows服务方式运行ASP.NET Core程序

    我们对ASP.NET Core的使用已经进行了相当一段时间了,大多数时候,我们的Web程序都是发布到Linux主机上的,当然了,偶尔也有需求要发布到Windows主机上,这样问题就来了,难道直接以控制 ...