建造者模式的概念
- 使用多个简单的对象,通过指定的顺序来一步步构建出一个复杂的对象.
- 用户并不需要知道内部是如何构建的,直接就可以创建出复杂的对象.
代码实现
建造者模式中有四个角色
- 抽象建造者(builder):描述具体的建造者的接口,只是用来定义建造的方法,不需要实现具体的细节.
- 具体建造者(ConcreteBuilder):实现抽象建造者的接口,并具体化建造过程.
- 指挥者(Director):调用具体的建造者,按照指定的顺序一步步构造出复杂饿对象(产品).
- 产品(Product):一个由各种简单对象组成的复杂对象.
代码实现
产品类-Hamburg 类
public class Hamburg {
private String Bread;
private String Sauce;
private String Lettuce;
private String Chick;
public String getBread() {
return Bread;
}
public void setBread(String bread) {
Bread = bread;
}
public String getSauce() {
return Sauce;
}
public void setSauce(String sauce) {
Sauce = sauce;
}
public String getLettuce() {
return Lettuce;
}
public void setLettuce(String lettuce) {
Lettuce = lettuce;
}
public String getChick() {
return Chick;
}
public void setChick(String chick) {
Chick = chick;
}
@Override
public String toString() {
return "Hamburg{" +
"Bread='" + Bread + ''' +
", Sauce='" + Sauce + ''' +
", Lettuce='" + Lettuce + ''' +
", Chick='" + Chick + ''' +
'}';
}
}
抽象建造者-Builder类
public abstract class Builder {
public abstract void openBread();
public abstract void smearSauce();
public abstract void putLettuce();
public abstract void putChick();
public abstract Hamburg createHamburg();
}
具体的建造者-HamburgBuilder类
public class HamburgBuilder extends Builder{
private Hamburg hamburg;
public HamburgBuilder(){
hamburg = new Hamburg();
}
@Override
public void openBread() {
hamburg.setBread("大面包");
}
@Override
public void smearSauce() {
hamburg.setSauce("辣酱");
}
@Override
public void putLettuce() {
hamburg.setLettuce("生菜");
}
@Override
public void putChick() {
hamburg.setChick("辣鸡肉");
}
@Override
public Hamburg createHamburg() {
return hamburg;
}
}
指挥类-Director类
public class Director {
public Hamburg makeHambury(Builder builder){
builder.openBread();
builder.smearSauce();
builder.putLettuce();
builder.putChick();
return builder.createHamburg();
}
}
测试类
public static void main(String[] args) throws CloneNotSupportedException {
Director director = new Director();
Hamburg hamburg = director.makeHambury(new HamburgBuilder());
System.out.println(hamburg);
}
执行结果
Hamburg{Bread='大面包', Sauce='辣酱', Lettuce='生菜', Chick='辣鸡肉'}
这样就组成了一个建造者模式.
扩展建造者模式
看了以上代码,感觉建造者模式好像并没有什么很大的作用,只是让代码看起来更加复杂,下面有一种更加常用的方式组建构造者模式
代码实现
Hamburg 类
public class Hamburg {
private String bread;
private String sauce;
private String lettuce;
private String chick;
private Hamburg(Builder builder){
this.bread = builder.bread;
this.sauce = builder.sauce;
this.lettuce = builder.lettuce;
this.chick = builder.chick;
}
public static final class Builder{
private String bread;
private String sauce;
private String lettuce;
private String chick;
public Builder setBread(String bread) {
this.bread = bread;
return this;
}
public Builder setSauce(String sauce) {
this.sauce = sauce;
return this;
}
public Builder setLettuce(String lettuce) {
this.lettuce = lettuce;
return this;
}
public Builder setChick(String chick) {
this.chick = chick;
return this;
}
public Hamburg createHamburg(){
return new Hamburg(this);
}
}
public String getBread() {
return bread;
}
public void setBread(String bread) {
this.bread = bread;
}
public String getSauce() {
return sauce;
}
public void setSauce(String sauce) {
this.sauce = sauce;
}
public String getLettuce() {
return lettuce;
}
public void setLettuce(String lettuce) {
this.lettuce = lettuce;
}
public String getChick() {
return chick;
}
public void setChick(String chick) {
this.chick = chick;
}
@Override
public String toString() {
return "Hamburg{" +
"bread='" + bread + ''' +
", sauce='" + sauce + ''' +
", lettuce='" + lettuce + ''' +
", chick='" + chick + ''' +
'}';
}
}
测试类
public static void main(String[] args) throws CloneNotSupportedException {
Hamburg hamburg = new Hamburg.Builder().setBread("小面包").setLettuce("苹果酱").setChick("鸡腿").createHamburg();
System.out.println(hamburg);
}
Hamburg{bread='小面包', sauce='null', lettuce='苹果酱', chick='鸡腿'}
这种方式是比较常用的建造者使用方式,他通过链式清晰明了的将对象构建出来.
其实在 lombok 中也 提供了 @Builder @SpuerBuilder这两个注解来实现上面的功能.
建造者模式的优缺点以及应用场景
优点
- 产品的建造和表示分离,实现了解耦。
- 将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰
- 增加新的具体建造者无需修改原有类库的代码,易于拓展,符合“开闭原则“
缺点
- 产品必须有共同点,限制了使用范围
- 如内部变化复杂,会有很多的建造类,难以维护
应用场景
- 需要生成的产品对象有复杂的内部结构,这些产品对象具备共性
- 隔离复杂对象的创建和使用,并使得相同的创建过程可以创建不同的产品
- 适合于一个具有较多的零件(属性)的产品(对象)的创建过程
建造者模式与工厂方法模式和抽象工厂模式的区别
建造者模式与工厂方法模式的区别
- 工厂方法模式注重的是整体对象的创建方式;
- 建造者模式注重的是部件构造的过程,意在一步步创建出符合自己需求的对象.
- 举例:我想吃一道菜,工厂方法模式就类似于预制菜,他的炒制过程以及食材都是一样的,我只需要加热就可以直接吃了;建造者模式就像是我自己一步一步的制作出这道菜,可以随自己的爱好选择步骤以及食材的不同.
- 工厂方法模式就是批量生产,建造者模式就是定制生产.
建造者模式与抽象工厂模式的区别
- 抽象工厂模式实现的是同一种类对象创建,但是属于不同维度的对象,他不需要关心构建过程,只要知道什么对象由什么对象的工厂生产即可.
- 建造者模式是按照指定的要求来生产,他的目的就是通过组装配件生产一个新的产品.
- 举例:抽象工厂模式就像汽车的配件生产工厂,指定的配件肯定是指定的工厂才可以生产;建造者模式就像是汽车的组装工厂,由各个零件组装成一辆完整的汽车,但是也可以通过修改不同的配件生产出另一辆全新的汽车