美文网首页
Builder模式

Builder模式

作者: Ray昱成 | 来源:发表于2018-12-14 12:57 被阅读0次

为何而来

假设有一个复杂对象example,里面有很多不可变属性(final)。实现方法通常有两种,一种是提供很多个构造方法用于实例化对象,另外一种是new一个对象,提供get/set方法。

两种方法的缺点:

  • 构造方法多而且参数多,代码可读性就很差,并且难以维护
  • 通过new对象然后set,在多线程或者其他情况下会产生对象不一致的状态。调用者看到了这个对象后,以为这个对象已经创建完毕,其实还没有具体初始化。

利用Builder模式,我们可以解决上面的问题

Builder模式例子

public class User {

    private final String firstName;     // 必传参数
    private final String lastName;      // 必传参数
    private final int age;              // 可选参数
    private final String phone;         // 可选参数
    private final String address;       // 可选参数

    private User(UserBuilder builder) {
        this.firstName = builder.firstName;
        this.lastName = builder.lastName;
        this.age = builder.age;
        this.phone = builder.phone;
        this.address = builder.address;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public int getAge() {
        return age;
    }

    public String getPhone() {
        return phone;
    }

    public String getAddress() {
        return address;
    }

    public static class UserBuilder {
        private final String firstName;
        private final String lastName;
        private int age;
        private String phone;
        private String address;

        public UserBuilder(String firstName, String lastName) {
            this.firstName = firstName;
            this.lastName = lastName;
        }

        public UserBuilder age(int age) {
            this.age = age;
            return this;
        }

        public UserBuilder phone(String phone) {
            this.phone = phone;
            return this;
        }

        public UserBuilder address(String address) {
            this.address = address;
            return this;
        }

        public User build() {
            return new User(this);
        }
    }
}

//创建User对象
new User.UserBuilder("张", "三")
                .age(20)
                .phone("123456789")
                .address("我在哪")
                .build();

通常情况下的基本原则:

  • User类的构造方法是私有的。也就是说调用者不能直接创建User对象
  • 类的属性都是不可变的。所有的属性都添加了final修饰符,并且在构造方法中设置了值。并且,对外只提供getters方法
  • Builder是静态内部类,构造方法中只接收必传的参数,并且对应的成员变量是final

Builder模式优缺点

  • 客户端的代码更容易写,使用了链式调用,可读性非常好
  • 不会产生同一对象不一致的状态
  • 会产生多余的Builder对象,消耗内存

线程安全与参数约束

User对象是不可变的,因此是线程安全的;但是,Builder对象并不具有线程安全性。因此,当我们需要对User对象的参数强加约束条件时,我们应该可以对builder()方法中所创建出来的User对象进行检验

public User build() {
  User user = new user(this);
  if (user.getAge() > 120) {
    throw new IllegalStateException(“Age out of range”); // 线程安全
  }
  return user;
}

需要特别注意的是,我们是对Person对象进行参数检查,而不是对Builder对象进行参数检查,因为Builder对象不是线程安全的,即下面的代码存在线程安全问题:

public User build() {
  if (age > 120) {
    throw new IllegalStateException(“Age out of range”); // 非线程安全
  }
  return new User(this);
}

经典的Builder模式

image.png

其中:

  • Product 产品抽象类。
  • Builder 抽象的Builder类。
  • ConcretBuilder 具体的Builder类。
  • Director 同一组装过程

mybatis中Builder模式用法

image.png

代码参考:https://www.jianshu.com/p/e2a2fe3555b9

相关文章

  • 设计模式:Builder

    Builder模式基本介绍Builder模式的实现源码中的Builder模式记录 Builder模式基本介绍 Bu...

  • Builder模式

    个人博客http://www.milovetingting.cn Builder模式 模式介绍 Builder模式...

  • Android中的构建者(Builder)模式

    目录一、场景分析二、定义三、Builder模式变种-链式调用四、经典Builder模式五、用到Builder模式的...

  • Builder模式

    Builder模式?(好熟悉,貌似有说不上来),在这里好好总结一下。 Builder模式的介绍 Builder模式...

  • 设计模式之构建者模式

    Builder属于创建型设计模式 Builder定义: Separate the construction of ...

  • 建造者模式

    建造者模式 创建型模式 Director、Builder、Product建造模型 Builder负责构建Produ...

  • Builder模式及原型模式

    本文主要内容 Builder模式定义 Builder模式 原型模式定义 原型模式 本文介绍两种简单的设计模式,Bu...

  • 11.2设计模式-构建者模式-详解

    构建者模式 java的builder模式详解 builder模式在android中的实际运用 1.java的bui...

  • 第 7 章 Builder 模式 -- 组装复杂的实例

    Builder 模式 概念:组装具有复杂结构的实例可以称为 Builder 模式。 Show me the cod...

  • 设计模式--Builder

    标签(空格分隔): android 设计模式 builder 1 Builder设计模式概述 将复杂对象的构建与它...

网友评论

      本文标题:Builder模式

      本文链接:https://www.haomeiwen.com/subject/vdwwhqtx.html