5d9fb9318396794e1cdde536fad10525
5分钟理解设计模式 —— 建造者模式

[TOC]

概述:

  5分钟理解设计模式系列,将通过解决实际问题,来带您理解设计模式,本文希望带您搞懂的3个问题是:

  1. 为什么我们需要建造者模式?
  2. 建造者模式和工厂模式的区别?
  3. 使用建造者模式,我们要先考虑些什么? ## 1.为什么我们需要建造者模式? 建造者模式(Builder),将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。 创建对象的方法有很多,我们最常用的方法就是,使用 new 关键字调用类的构造函数来完成。举个例子,我们设计了一个学生类,分别有班级、姓名、学号、出生日期、年龄。接下来我们通过new关键字创建对象.
Student xiaofei = new Student("计算机1班""小肥"2015407020119"1997-04-09"23);

此时因为学生类只有5个字段,所以看起来直接使用new关键字创建对象的方法没什么问题,但是如果一个类的字段比较多,就容易导致代码可读性差、参数可能传递错误等问题。
这个时候我们可以用这个类的无参构造方法创建对象,然后调用他的setter方法去为对象赋值。

Student xiaofei = new Student();
xiaofei.setClassName("计算机1班");
xiaofei.setName("小肥");
xiaofei.setNumber(2015407020119);
xiaofei.setBirthday("1997-04-09");
xiaofei.setAge(23);

思考一下,这样做有没有什么问题?
这样做主要有3个问题:
1 如果有对象属性是必填的,那么我们就需要在构造函数中进行赋值,如果必填属性多的话,那么使用set方法赋值就会退化成使用构造函数赋值。
2 如果对象属性是相互关联的,比如我们需要校验生日和出生日期的关系,那么这部分逻辑就没有办法放置。
3 如果我们希望学生类是一个不可变对象,那么我们就不能暴露它的setter方法。
我们可以通过建造者解模式来决以上三个问题,关键代码如下:

public class StudentBuilder {
    private String className;
    private String name;
    private Long number;
    private String birthday;
    private int age;

    public StudentBuilder setClassName(String className) {
        // 输入值的校验可以写在setter方法里
        if (StringUtils.isEmpty(name)) {
            throw new IllegalArgumentException("...");
        }
        this.className = className;
        return this;
    }

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

    public StudentBuilder setNumber(Long number) {
        this.number = number;
        return this;
    }

    public StudentBuilder setBirthday(String birthday) {
        this.birthday = birthday;
        return this;
    }

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

    public Student build() {
        // 属性值之间的校验可以集中写在这里,比如校验生日和年龄的关系
        return new Student(this.className, this.name, this.number, this.birthday, this.age);
    }
}
public class Main {
    public static void main(String[] args) {
        Student student = new StudentBuilder()
                .setAge(23)
                .setName("小肥")
                .setBirthday("1997-04-09")
                .setClassName("计算机1班")
                .setNumber(2015407020119L)
                .build();
        System.out.println(student.toString());
    }
}

执行结果:

Student{className='计算机1班', Name='小肥', number=2015407020119, birthday='1997-04-09', age=23}

2.建造者模式和工厂模式的区别?

1 工厂模式可以创建一类对象,根据条件决定创建那个对象。
2 建造者模式是针对与一个对象,将它的构建和使用解耦,也可以根据不同的构建方法去定制化的创建对象。
总结来说:工厂模式关注创建哪个对象,建造者模式关注如何创建对象。

3.使用建造者模式,我们要先考虑些什么?

我们在使用所有设计模式的时候,都应该思考我们究竟需不需要使用该模式,因为设计模式的出发点都是为了解决实际问题。有句话说的好,当你的手里拿着锤子,你的眼里看哪都是钉子,所有的设计模式在一定程度上都会影响代码的可读性,在使用设计模式的时候,我们也应该要牢记KISS原则——Keep It Simple and Stupid ,简洁最美。
(题外话:博主在刚学建造者模式的时候,就想立即应用到项目中,当时做对象转换的时候,都不去写转换器,而是直接通过建造者模式去处理,虽然可以实现功能,但是如果别人看代码的话,就会觉得很怪)

最后,期待您的订阅和点赞,专栏每周都会更新,希望可以和您一起进步,同时也期待您的批评与指正!

© 著作权归作者所有
这个作品真棒,我要支持一下!
一个坚持原创的小专栏。分享编程知识,提升工作效率,致力于通过简单的语言,把编程这点事讲清楚。涵盖内容:java、设...
0条评论
top Created with Sketch.