【Java设计模式】五、建造者模式

文章目录

1、建造者模式

  • 某个对象的构建复杂
  • 将复杂的对象的创建 和 属性赋值所分离,使得同样的构建过程可以创建不同的表示
  • 建造的过程和细节调用者不需要知道,只需要通过构建者去进行操作

如,主机这个负责对象的构建,分离承诺内存条、主板这些部件,再组装构建。内存条替换一个别的,出来就是一个不同的对象。

建造者模式相关角色:

  • 产品类:复杂对象,主机
  • 抽象建造者类Builder:规定要实现复杂对象的哪些部件的创建
  • 具体建造者类ConcreteBuilder:实现Builder,完成各个部件的具体创建
  • 指挥者类Director:保证对象的各个部分按照某种顺序创建

2、案例:共享单车的创建

摩拜单车和ofo单车。Bike是产品,包含车架,车座等组件;Builder是抽象建造者,MobikeBuilder和OfoBuilder是具体的建造者,Director是指挥者。

具体的代码如下:

java 复制代码
//自行车类
@Data
public class Bike {
    private String frame;  //车架
    private String seat;   //座椅


}

抽象构建者Builder定义哪些部分要构建:

java 复制代码
// 抽象 builder 类
public abstract class Builder {

    protected Bike mBike = new Bike();

    public abstract void buildFrame();   //构建车架
    public abstract void buildSeat();    //构建座椅
    public abstract Bike createBike();   //构建自行车
    
}

写具体的构建者:

java 复制代码
//摩拜单车Builder类
public class MobikeBuilder extends Builder {

    @Override
    public void buildFrame() {
        mBike.setFrame("铝合金车架");
    }

    @Override
    public void buildSeat() {
        mBike.setSeat("真皮车座");
    }

    @Override
    public Bike createBike() {
        return mBike;
    }
}
java 复制代码
//ofo单车Builder类
public class OfoBuilder extends Builder {

    @Override
    public void buildFrame() {
        mBike.setFrame("碳纤维车架");
    }

    @Override
    public void buildSeat() {
        mBike.setSeat("橡胶车座");
    }

    @Override
    public Bike createBike() {
        return mBike;
    }
}

指挥者类:

java 复制代码
//指挥者类
public class Director {
    private Builder mBuilder;   //声明Builder类型的变量

    public Director(Builder builder) {
        mBuilder = builder;
    }
	
	//组装自行车的方法
    public Bike construct() {
        mBuilder.buildFrame();
        mBuilder.buildSeat();
        return mBuilder.createBike();
    }
}

客户端测试:

java 复制代码
public class Client {
    public static void main(String[] args) {
        showBike(new OfoBuilder());
        showBike(new MobikeBuilder());
    }
    private static void showBike(Builder builder) {
        Director director = new Director(builder);   //创建指挥者
        Bike bike = director.construct();   //让指挥者指挥组装
        System.out.println(bike.getFrame());
        System.out.println(bike.getSeat());
    }
}

再有新的单车公司加入,只需实现一个新的建造者类即可,符合开闭原则。但如果创建的产品组成部分差异很大,则不适合用建造者模式,比如要再造个电脑对象。

3、其他用途

java 复制代码
@Setter
@Getter
public class Phone {
    private String cpu;
    private String screen;
    private String memory;
    private String mainboard;

    public Phone(String cpu, String screen, String memory, String mainboard) {
        this.cpu = cpu;
        this.screen = screen;
        this.memory = memory;
        this.mainboard = mainboard;
    }
}

对于属性多的对象,创建其对象往往可读性很差,如:

java 复制代码
//构建Phone对象
Phone phone = new Phone("intel","三星屏幕","金士顿","华硕");

重构一下(@Builder注解的思路):

java 复制代码
public class Phone {

    private String cpu;
    private String screen;
    private String memory;
    private String mainboard;
	
	//私有的构造方法
    private Phone(Builder builder) {
        cpu = builder.cpu;
        screen = builder.screen;
        memory = builder.memory;
        mainboard = builder.mainboard;
    }

    public static final class Builder {
        private String cpu;
        private String screen;
        private String memory;
        private String mainboard;

        public Builder() {}

        public Builder cpu(String val) {
            cpu = val;
            return this;
        }
        public Builder screen(String val) {
            screen = val;
            return this;
        }
        public Builder memory(String val) {
            memory = val;
            return this;
        }
        public Builder mainboard(String val) {
            mainboard = val;
            return this;
        }
        //!!!!!
        public Phone build() {
            return new Phone(this);
         }
    }
    @Override
    public String toString() {
        return "Phone{" +
                "cpu='" + cpu + '\'' +
                ", screen='" + screen + '\'' +
                ", memory='" + memory + '\'' +
                ", mainboard='" + mainboard + '\'' +
                '}';
    }
}

此时就可链式编程创建这个对象(new Phone.Builder()创建静态内部类对象):

java 复制代码
public class Client {
    public static void main(String[] args) {
        Phone phone = new Phone.Builder()
                .cpu("intel")
                .mainboard("华硕主板")
                .memory("金士顿内存")
                .screen("三星屏幕")
                .build();
        System.out.println(phone);
    }
}
相关推荐
Yyyy48210 分钟前
MyCAT高可用
java·运维
华仔啊1 小时前
final在Java中到底有啥用?5个实际场景告诉你
java·后端
the beard1 小时前
Maven 入门与进阶:聚合、继承与生命周期详解
java
楚禾Noah1 小时前
【设计模式实战】原型模式 + 工厂模式:AI Agent 配置中心
人工智能·设计模式·原型模式
csdn_aspnet1 小时前
解决 Spring Boot 应用程序中的“无法配置数据源”错误
java·spring boot
Pure_Eyes1 小时前
设计模式详解
设计模式
hai_qin1 小时前
三,设计模式-抽象工厂模式
c++·设计模式·抽象工厂模式
灵魂猎手1 小时前
9. Mybatis与Spring集成原理解析
java·后端·源码
AAA修煤气灶刘哥2 小时前
避坑!线程 / 线程池从入门到华为云实战,面试官听了都点头
java·后端·面试
Agome992 小时前
Docker之nginx安装
java·nginx·docker