一、概念
建造者模式(Bulider Pattern)
指将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式
二、建造者模式的四个角色
- 产品类(Product):一般是一个较为复杂的对象,也就是说创建对象的过程比较复杂,它通常包含多个部分或者组成,并由具体的建造者逐步构建而成。
- 抽象建造者(Builder):定义了建造复杂对象所需要的各个部分的创建方法。它通常包括多个构建方法和一个返回产品的方法。一般由子类实现具体的建造过程。
- 具体建造者类(ConcreteBuilder):实现抽象类的所有未实现的方法,具体来说一般是两项任务:组建产品;返回组建好的产品。
- 指挥者类(Director):负责控制建造者的构建顺序,指挥建造者如何构建复杂对象。
/**
* 产品类(Product)
*/
@Data
class Meal {
//汉堡
private String burger;
//小吃
private String snack;
//饮料
private String drink;
}
/**
* 抽象建造者(Builder)
*/
abstract class Builder {
protected Meal meal=new Meal();
//构建汉堡
public abstract void buildBurger();
//构建小吃
public abstract void buildSnack();
//构建饮料
public abstract void buildDrink();
//返回实例
public Meal getMeal(){
return meal;
}
}
/**
*
* 具体建造者(ConcreteBuilder):鸡肉汉堡套餐
*/
class ChickenMealBuilder extends Builder{
@Override
public void buildBurger() {
meal.setBurger("鸡肉汉堡");
}
@Override
public void buildSnack() {
meal.setSnack("炸鸡块");
}
@Override
public void buildDrink() {
meal.setDrink("可乐");
}
}
/**
* 具体建造者(ConcreteBuilder):牛肉汉堡套餐
*/
class BeefMealBuilder extends Builder {
@Override
public void buildBurger() {
meal.setBurger("牛肉汉堡");
}
@Override
public void buildSnack() {
meal.setSnack("薯条");
}
@Override
public void buildDrink() {
meal.setDrink("果汁");
}
}
/**
* 指挥者类(Director)
*/
class MealDiretor {
private Builder builder;
public void setMealBuilder(Builder builder){
this.builder=builder;
}
public Meal getMeal(){
return builder.getMeal();
}
//制作套餐
public void constructMeal(){
builder.buildBurger();
builder.buildSnack();
builder.buildDrink();
}
}
public class TestBuilder {
public static void main(String[] args) {
// 创建指挥者类
MealDiretor diretor=new MealDiretor();
//执导建造牛肉套餐
diretor.setMealBuilder(new BeefMealBuilder());
diretor.constructMeal();
Meal meal = diretor.getMeal();
System.out.println("牛肉套餐:"+meal.toString());
//鸡肉套餐
diretor.setMealBuilder(new ChickenMealBuilder());
diretor.constructMeal();
Meal meal1 = diretor.getMeal();
System.out.println("鸡肉套餐:"+meal1.toString());
}
}
三、建造者模式优缺点
建造者模式优点 :
封装性好 : 创建 和 使用 分离 。
扩展性好 : 建造类之间 相互独立 , 在 一定程度上解耦 。
建造者模式缺点 :
增加类数量 : 产生多余的 Builder 对象 。
内部修改困难 : 如果 产品内部发生变化 , 建造者也要相应修改 ,代码维护困难。
四、建造者模式应用场景
当类中的属性参数很多且属性与属性之间有依赖关系既可以使用建造者模式,一般情况,构造器和set方法组合方法即可。
建造者链式调用
@Data
class Student {
private String name;
private String age;
private String number;
private String address;
private String school;
public Student(StudentBuilder builder) {
this.name = builder.name;
this.age = builder.age;
this.number = builder.number;
this.address = builder.address;
this.school = builder.school;
}
/**
* 使用静态内部类作为创建者
* 将具体的业务类 及其 创建者 定义在一个类中
* 使用链式调用 , 每个 build 步骤都返回创建者本身
*/
public static class StudentBuilder {
private String name;
private String age;
private String number;
private String address;
private String school;
public StudentBuilder buildName(String name) {
this.name = name;
return this;
}
public StudentBuilder buildAge(String age) {
this.age = age;
return this;
}
public StudentBuilder buildNumber(String number) {
this.number = number;
return this;
}
public StudentBuilder buildAddress(String address) {
this.address = address;
return this;
}
public StudentBuilder buildSchool(String school) {
this.school = school;
return this;
}
public Student build() {
return new Student(this);
}
}
}
public class Main {
public static void main(String[] args) {
// 使用链式调用 , 一行代码创建实例对象
Student student = new Student.StudentBuilder()
.buildName("小明")
.buildAge("12")
.buildNumber("1")
.buildAddress("学院路")
.buildSchool("第一小学")
.build();
System.out.println(student);
}
}
使用lombok中的@Builder注解简化代码
@Data
@Builder
class Student {
private String name;
private String age;
private String number;
private String address;
private String school;
}
public class Main {
public static void main(String[] args) {
// 使用链式调用 , 一行代码创建实例对象
Student student = Student.builder()
.name("小明")
.age("12")
.number("1")
.address("学院路")
.school("第一小学")
.build();
System.out.println(student);
}
}