03-JAVA设计模式-建造者模式

建造者模式

什么是建造者模式

建造者模式(Builder Pattern)是一种对象构建的设计模式,它允许你通过一步一步地构建一个复杂对象,来隐藏复杂对象的创建细节。

这种模式将一个复杂对象的构建过程与其表示过程分离,使得同样的构建过程可以创建不同的表示。命名建议以Builder结尾,以达到见名之意。

在建造者模式中,通常包含以下几个角色:

  • **产品(Product):**这是最终要创建的对象,它通常包含多个属性,并且可能具有复杂的内部结构。
  • **抽象建造者(Builder):**这是一个接口或者抽象类,定义了创建产品所需的方法。这些方法通常是一系列设置产品属性的步骤。
  • **具体建造者(ConcreteBuilder):**这个类实现了抽象建造者接口,提供了构建产品的具体实现。它包含了创建产品对象的所有逻辑,并可以一步步地设置产品对象的属性。
  • **导演者(Director):**这是一个可选的角色,它负责调用建造者接口中的方法来构建产品对象。导演者可以简化客户端代码,使得客户端无需关心具体的构建步骤。

使用场景

  • 当我们要建造一个复杂的产品。比如:手机时。这种复杂产品的创建,需要处理子组件装配的问题。
  • 实际开发中,我们所需要的对象构建时也非常复杂,有很多步骤需要处理时。

建造者模式的本质

  • 分离了对象子组件的单独构造(有Buider来负责)和装配(有Director负责)。从而可以构造负责的对象。
  • 这个模式适用于在某个对象构建过程复杂的情况下使用。
  • 由于实现了构建和装配的解耦。不同的构建器,相同的装配,可以做出不同的对象; 相同的构建器,不同的装配顺序也可以做出不同的对象。也就是实现了构建算法、装配算法的解耦,实现了更好的复用。

案例

实现建造华为手机与小米手机

通过静态内部类作为建造者

Phone.java

java 复制代码
public class Phone {
    // 机身
    private String fuselage;
    // 摄像头
    private String camera;
    // 系统内核
    private String systemKernel;

    // 私有构造方法,只能通过建造者创建
    private Phone(Builder builder) {
        this.fuselage = builder.fuselage;
        this.camera = builder.camera;
        this.systemKernel = builder.systemKernel;
    }

    @Override
    public String toString() {
        return "Phone{" +
                "fuselage='" + fuselage + '\'' +
                ", camera='" + camera + '\'' +
                ", systemKernel='" + systemKernel + '\'' +
                '}';
    }

    // 静态内部类作为建造者
    static class Builder {
        // 机身
        private String fuselage;
        // 摄像头
        private String camera;
        // 系统内核
        private String systemKernel;

        public Builder setFuselage(String fuselage) {
            this.fuselage = fuselage;
            return this;    // 链式调用
        }

        public Builder setCamera(String camera) {
            this.camera = camera;
            return this;    // 链式调用
        }

        public Builder setSystemKernel(String systemKernel) {
            this.systemKernel = systemKernel;
            return this;    // 链式调用
        }

        // 创建手机
        public Phone createPhone(){
            return new Phone(this);
        }
    }
}

Client.java

java 复制代码
public class Client {
    public static void main(String[] args) {
        Phone phone = new Phone.Builder()
                .setCamera("华为摄像头")
                .setFuselage("华为机身")
                .setSystemKernel("鸿蒙系统")
                .createPhone();
        System.out.println(phone);

        Phone phone2 = new Phone.Builder()
                .setCamera("小米摄像头")
                .setFuselage("小米机身")
                .setSystemKernel("小米系统")
                .createPhone();
        System.out.println(phone2);
    }
}

执行结果:

通过接口实现建造者模式

UML
不使用导演者

Phone.java

java 复制代码
public class Phone {
    // 机身
    private String fuselage;
    // 摄像头
    private String camera;
    // 系统内核
    private String systemKernel;

    public void setFuselage(String fuselage) {
        this.fuselage = fuselage;
    }

    public void setCamera(String camera) {
        this.camera = camera;
    }

    public void setSystemKernel(String systemKernel) {
        this.systemKernel = systemKernel;
    }

    @Override
    public String toString() {
        return "Phone{" +
                "fuselage=" + fuselage +
                ", camera=" + camera +
                ", systemKernel=" + systemKernel +
                '}';
    }
}

IPhoneBuider.java

java 复制代码
// 手机 抽象建造者定义接口
public interface IPhoneBuider {
    // 设置机身
    IPhoneBuider setFuselage(String fuselage);
    // 设置摄像头
    IPhoneBuider setCamera(String camera);
    // 设置系统内核
    IPhoneBuider setSystemKernel(String systemKernel);
    // 返回创建对象
    Phone buildPhone();
}

PhoneBuilder.java

java 复制代码
// 建造者具体实现
public class PhoneBuilder implements IPhoneBuider {
    // 定义建造者返回对象
    private Phone phone;
    public PhoneBuilder() {
        // 初始化Phone
        this.phone = new Phone();
    }
    @Override
    public IPhoneBuider setFuselage(String fuselage) {
        phone.setFuselage(fuselage);
        return this;
    }
    @Override
    public IPhoneBuider setCamera(String camera) {
        phone.setCamera(camera);
        return this;
    }
    @Override
    public IPhoneBuider setSystemKernel(String systemKernel) {
        phone.setSystemKernel(systemKernel);
        return this;
    }
    @Override
    public Phone buildPhone() {
        return phone;
    }
}

TestClient2.java

java 复制代码
public class TestClient2 {
    public static void main(String[] args) {
        // 创建建造具体建造者
        PhoneBuilder phoneBuilder = new PhoneBuilder();

        Phone phone = phoneBuilder
                .setCamera("装配小米摄像头")
                .setFuselage("装配小米机身")
                .setSystemKernel("装配小米系统")
                .buildPhone();

        System.out.println(phone.toString());

    }
}
使用导演者

新增导演者

HuaweiDirector.java

java 复制代码
// 华为手机导演者
public class HuaweiDirector {
    // 定义建造者属性
    private IPhoneBuider phoneBuider;

    public HuaweiDirector(IPhoneBuider phoneBuider) {
        this.phoneBuider = phoneBuider;
    }

    public Phone createPhone(){
        Phone phone = phoneBuider.setCamera("装配华为摄像头")
                .setFuselage("装配华为机身")
                .setSystemKernel("装配鸿蒙系统")
                .buildPhone();
        return phone;
    }
}

TestClient.java

java 复制代码
public class TestClient {
    public static void main(String[] args) {
        // 创建建造具体建造者
        PhoneBuilder phoneBuilder = new PhoneBuilder();
        // 创建导演者 传入具体建造者
        HuaweiDirector huaweiDirector = new HuaweiDirector(phoneBuilder);
        // 通过导演者构建手机
        Phone phone = huaweiDirector.createPhone();
        System.out.println(phone.toString());
    }
}

gitee源码

git clone https://gitee.com/dchh/JavaStudyWorkSpaces.git

相关推荐
aibo8603082 分钟前
基于 Spring Boot + Vue3 的菜谱分享网站设计与实现
java·spring boot·后端
凤山老林3 分钟前
Spring Boot 集成 TOTP 双因素认证与恢复码机制
java·spring boot·后端
小冯不疯6 分钟前
物料主数据同步实战:从金蝶云星空到小满OKKICRM的单一策略深度拆解
java·大数据·数据库
vipxieliang9 分钟前
Spring Boot 测试策略:单元测试、切片测试与集成测试
java·spring boot·后端
估值探索者21 分钟前
【Python量化技术指标实战 04】布林带通道突破,怎么知道是真突破还是假突破?
java·开发语言·python·接口·股票数据api接口
未秃头的程序猿21 分钟前
同一个商户号,V2 免密代扣和 V3 分账的证书怎么共存?
java·后端·微信
captain37636 分钟前
Spring Boot的配置文件
java·spring boot·后端
captain37637 分钟前
Spring Boot日志
java·数据库·spring boot
Rabitebla1 小时前
【Linux】 权限篇(三):深入理解 umask 位运算与粘滞位的设计思想
java·linux·服务器·c++·笔记·学习
Pin_Qing1 小时前
缓存能活多久,现在是个要算的参数
java·大数据·开发语言·人工智能·程序人生