专栏首页Java识堂用建造者模式实现链式赋值,代码真清爽

用建造者模式实现链式赋值,代码真清爽

介绍

前段时间写了个项目,一个类的属性那叫一个多啊。刚开始直接写一堆set代码,后来set代码实在是太多了,真心看不下去了,用建造者模式重构了一下,嗯,看起来舒服多了。基本上很多框架中都用到了建造者模式,每个Java程序员也肯定用过建造者模式,只不过你没有意识到这就是建造者模式。

就像你用Collections.sort(List,Comparator)和Arrays.sort(Object[],Comparator)的时候是否意识这就是策略模式的典型实现,通过传入不同的比较器来达到不同的效果。

改造过程

先来演示一下我改造的过程,用了Lombok插件,不会的可以百度一下。

原来的实现

@Data
public class Student {

    private String name;
    private int age;
    private int gender;
}

测试类

public class Test {

    public static void main(String[] args) {
        Student student = new Student();
        student.setName("小明");
        student.setAge(10);
        student.setGender(1);
        // Student(name=小明, age=10, gender=1)
        System.out.println(student);
    }
}

后来的实现

@Data
@Builder
public class Student {

    private String name;
    private int age;
    private int gender;
}

测试类

public class Test {

    public static void main(String[] args) {
        Student student = Student.builder().name("小明")
                .age(10).gender(1).build();
        // Student(name=小明, age=10, gender=1)
        System.out.println(student);
    }
}

全程链式调用,清晰知道每个字段的含义,而且还节省行数,不能太爽。

如何写建造者模式?

直接看最后编译生成的class文件反编译后的内容

public class Student {
    private String name;
    private int age;
    private int gender;

    Student(String name, int age, int gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    public static Student.StudentBuilder builder() {
        return new Student.StudentBuilder();
    }

    // 省略get和set方法

    public String toString() {
        return "Student(name=" + this.getName() + ", age=" + this.getAge() + ", gender=" + this.getGender() + ")";
    }

    public static class StudentBuilder {
        private String name;
        private int age;
        private int gender;

        StudentBuilder() {
        }

        public Student.StudentBuilder name(String name) {
            this.name = name;
            return this;
        }

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

        public Student.StudentBuilder gender(int gender) {
            this.gender = gender;
            return this;
        }

        public Student build() {
            return new Student(this.name, this.age, this.gender);
        }

    }
}

我觉得我不用解释你都能看懂这个代码的意思,也就两部分。

1.生成建造者类,给建造者类赋值 2.用建造者类生成想要的类

恭喜你,已经看懂什么是建造者模式了。

Lombok中@Builder注解的使用

如果你的项目中可以用Lombok插件,就不用自己手写建造者类了,直接用@Builder注解即可。如果不可以,仿造上面的类写一个建造者类也是很快的。@Builder注解需要注意的地方有如下几点。

没有继承的情况

上面已经演示了

有继承的情况

1.对于父类,使用@AllArgsConstructor注解 2.对于子类,手动编写全参数构造器,内部调用父类全参数构造器,在子类全参数构造器上使用@Builder注解

@Data
@AllArgsConstructor
public class Person {

    private int weight;
    private int height;
}
@Data
@ToString(callSuper = true)
public class Student extends Person {

    private String schoolName;
    private String grade;

    @Builder
    public Student(int weight, int height, String schoolName, String grade) {
        super(weight, height);
        this.schoolName = schoolName;
        this.grade = grade;
    }

    public static void main(String[] args) {

        Student student = Student.builder().schoolName("清华附小").grade("二年级")
                .weight(10).height(10).build();

        // Student(super=Person(weight=10, height=10), schoolName=清华附小, grade=二年级)
        System.out.println(student.toString());
    }
}

在框架中的应用

基本上所有的Java框架都用到了建造者模式,因为链式赋值真的很爽。我Google了一点用了建造者模式的代码,方便大家理解。整体思路一样,可能具体实现略微有点差别。

Guava Cache框架

Cache<String,String> cache = CacheBuilder.newBuilder()
        .maximumSize(2)
        .expireAfterWrite(3,TimeUnit.SECONDS)
        .build();

本文分享自微信公众号 - Java识堂(erlieStar),作者:李立敏

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-08-11

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

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Java自定义注解及应用

    注解是在jdk1.5之后引入的,极大的方便了我们编写程序,并且上文Spring中XML,注解,JavaConfig如何选择,就说了用注解和JavaConfig比...

    Java识堂
  • 手写了一个Spring MVC

    我们先手写一个Spring MVC,让你对Spring MVC的整体实现有一个基本的认识

    Java识堂
  • Spring MVC 异常解析器,原理就是这么简单

    因为@ExceptionHandler注解的方式已经足够强大,所以我们一般也很少通过实现HandlerExceptionResolver来自定义异常处理策略。

    Java识堂
  • 泛型

    葆宁
  • 安卓第七夜 雅典学院

    我之前只使用了一种持续保存数据的方法,即SharedPreferences。然而,SharedPreferences只能存储少量松散的数据,并不适合大量数据的存...

    Vamei
  • 创建型设计模式:Builder Pattern示例介绍

    在此之前,我们了解了工厂和抽象工厂模式。这些模式很有用。然而,有几个案例需要创建一个非常复杂的对象,它需要不同的步骤和操作。在这种情况下,Builder Pat...

    程序你好
  • 关于Spring属性处理器PropertyResolver以及应用运行环境Environment的深度分析,强大的StringValueResolver使用和解析【享学Spring】

    若直接提PropertyResolver或者StringValueResolver可能很小伙伴会觉得非常的陌生,但是我若提Environment和Embedde...

    YourBatman
  • 组合模式

    tanoak
  • 教你用构建者(生成器)模式优雅地创建对象

    很多博客文章上来就先抛出一个定义,我们不妨反过来问一句为什么要用构建者模式。 首先我们创建一个User类,然后采用有参构造器的方式创建对象。

    java技术爱好者
  • 聊聊rocketmq的registerConsumer与unregisterConsumer

    本文主要研究一下rocketmq的registerConsumer与unregisterConsumer

    codecraft

扫码关注云+社区

领取腾讯云代金券