博文原址:折腾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. typecho设置文章密码保护

    在别人博客看到了一个需要输入密码才能访问文章的功能,像下图一样 typecho也是有这个功能,不需要插件就可以实现.在编辑文章时,右边高级选项,公开度里有个密码保护可以选择 效果图 不过这样的界面不是 ...

  2. kolla 多节点部署 openstack

    kolla 介绍 简介 kolla 的使命是为 openstack 云平台提供生产级别的.开箱即用的交付能力.kolla 的基本思想是一切皆容器,将所有服务基于 Docker 运行,并且保证一个容器只 ...

  3. javascript数组的常用算法解析

    一.不改变原数组,返回新数组(字符串) 1.concat()   连接两个或者多个数组,两边的原始数组都不会变化,返回的是被连接数组的一个副本. 2.join()  把数组中所有的元素放入到一个字符串 ...

  4. 第3章 结束会话端点(EndSession Point) - IdentityModel 中文文档(v1.0.0)

    该RequestUrl类可用于构造URL发送到OpenID Connect EndSession endpoint. 该CreateEndSessionUrl扩展方法支持最常用的参数: /// < ...

  5. 笔记:Java虚拟机运行时数据区

    Java虚拟机在执行Java程序的过程中会把它管的内存划分为以下若干个不同的区域: 1.程序计数器 程序计数器是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器:由于Java虚拟机的 ...

  6. spring2.0 Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definiti

    1. 报错信息 Description: The bean 'dataSource', defined in BeanDefinition defined in class path resource ...

  7. asp.net Core 中AuthorizationHandler 实现自定义授权

    前言 ASP.NET Core 中 继承的是AuthorizationHandler ,而ASP.NET Framework 中继承的是AuthorizeAttribute. 它们都是用过重写里面的方 ...

  8. arcgis api 4.x for js 离线部署

    在我的GIS之家群里,经常遇到 webgis 开发新手们提问 arcgis api for js 如何本地离线部署,而不是直接调用在线的,因为在线模式依赖互联网以及网速环境因素,受到的限制影响比较大. ...

  9. Win10常见问题记录

    基本信息 记录我在使用win10过程中遇到的一些问题 我所使用的两个win10系统 Win10 企业版 1607(家里电脑) Win10 专业版 1806(公司电脑) win10 开启Sets 请问您 ...

  10. Windows -- cmd命令: ipconfig 和 nbtstat

    1. ipconfig 命令格式及参数如下: 2. nbtstat 命令格式及参数如下: