【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);
    }
}
相关推荐
Gauss松鼠会15 小时前
GaussDB(DWS) GUC参数修改、查看
java·数据库·sql·数据库开发·gaussdb
AIFQuant15 小时前
Java 对接全球股票实时报价:高可用架构与异常处理
java·开发语言·websocket·金融·架构·股票api
未若君雅裁15 小时前
Spring Bean 作用域、线程安全与生命周期
java·安全·spring
奋斗的小乌龟15 小时前
langchain4j笔记-智能体系统01
java·笔记
wh_xia_jun15 小时前
用pom 的test 配置 与 jacoco
java·ide·intellij-idea
阿丰资源15 小时前
基于Spring Boot的酒店客房管理系统
java·spring boot·后端
无籽西瓜a16 小时前
【西瓜带你学Kafka | 第八期】 Kafka的主从同步、消息可靠性、流处理与顺序消费(文含图解)
java·分布式·后端·kafka·消息队列·mq
布吉岛的石头16 小时前
Java 程序员第 18 阶段:实战Agent工作流:Java搭建自动化业务智能体
java·python·自动化
zzqssliu16 小时前
SpringBoot框架搭建跨境独立站|Taocarts代购系统订单模块深度开发
java·spring boot·后端
dinl_vin16 小时前
FastAPI 系列 ·(四):数据库集成——SQLAlchemy 2.0 异步 ORM 与 Alembic 迁移
java·数据库·fastapi