建造者模式
一. 说明
建造者模式也是一种较少使用的创建型模式,官方的介绍是将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
用白话文说就是可以将许多简单对象随意组合成不同复杂对象,复杂对象的构建过程是固定的,构建的组成部分却是可以随意组合的。这个模式在java开发中自己实现的场景并不多见,如果你使用过lombok,你就知道在用@Builder注解实体对象时,这就是一个建造者模式的应用。
二.应用场景
- lombok插件的@Builder注解的类
- 装修房子时装修的过程是固定的但选择不同的部件或材料,最终的风格是不一样的
- 点菜套餐:套餐是由多个食物和饮品构造,但不同的食物和饮品组合成的套餐也不一样
- 游戏中制作角色时,角色的构造是不变的(头,身体,手,脚等),但角色的每个部件样子确实多样组合的。
三.代码示例
我们以构建游戏人物为例,首先创建一个人物实体,人物由多个部件构成
public class Person {
List<String> parts = new ArrayList<>();
public void add(String part) {
parts.add(part);
}
public void show() {
System.out.println("person构成:");
parts.forEach(p -> System.out.println(p));
}
}
其次创建一个抽象建造者,建造者负责组合建造人物部件
public abstract class Builder {
abstract void buildHead();
abstract void buildBody();
abstract void buildArm();
abstract void buildLeg();
abstract Person getPerson();
public void build(){
buildHead();
buildBody();
buildArm();
buildLeg();
}
}
我们再创建两个人物,一个强壮的人,一个瘦弱的人
public class StrongPerson extends Builder{
private Person person = new Person();
@Override
void buildHead() {
person.add("大头");
}
@Override
void buildBody() {
person.add("强壮的身躯");
}
@Override
void buildArm() {
person.add("长手臂");
}
@Override
void buildLeg() {
person.add("长腿");
}
@Override
Person getPerson() {
return person;
}
}
public class ThinPerson extends Builder{
private Person person = new Person();
@Override
void buildHead() {
person.add("小头");
}
@Override
void buildBody() {
person.add("瘦弱的身躯");
}
@Override
void buildArm() {
person.add("断臂");
}
@Override
void buildLeg() {
person.add("短腿");
}
@Override
Person getPerson() {
return person;
}
}
编写测试代码, 输出测试结果
public static void main(String[] args) {
StrongPerson strong = new StrongPerson();
strong.build();
strong.getPerson().show();
System.out.println("-------------");
ThinPerson thin = new ThinPerson();
thin.build();
thin.getPerson().show();
}
至此,一个简单的建造者模式的例子就写完了,抽象建造者固定并隐藏了建造过程,具体部件由具体实体选择绘制。
四. lombok中的@Builder
我们再来看看lombok中的建造者模式是如何使用和实现的,我们先写一个应用的demo代码。
@Builder
@Data
public class Student {
private String name;
private String sex;
private int age;
public static void main(String[] args) {
Student student = Student.builder()
.name("张三")
.sex("男")
.age(18)
.build();
System.out.println(student.toString());
}
}
使用lombok的@Builder注解,可以将一个类的属性当成组成对象的部件,由开发者随意编织。lombok在类的内部生成了一个公开的静态内部类,以该类名+Builder为命名,将该类的所有属性复制到内部类中并生成每个属性赋值的方法 ,最后用build()方法创建并复制对象。
public static class StudentBuilder {
private String name;
private String sex;
private int age;
StudentBuilder() {
}
public StudentBuilder name(final String name) {
this.name = name;
return this;
}
public StudentBuilder sex(final String sex) {
this.sex = sex;
return this;
}
public StudentBuilder age(final int age) {
this.age = age;
return this;
}
public Student build() {
return new Student(this.name, this.sex, this.age);
}
}
五. 总结
通过对建造者模式的学习,我们可以总结出一些心得,一些基本过程或物料不会变,其组合会发生变化时,就可以使用这个模式来构建代码。