设计模式之建造者模式

前言:

很多设计模式,都继承到了spring中,比如说模板模式,单例模式,代理模式,观察者模式等等,以至于我们平时都没有感觉到自己用到了设计模式,那今天讲到的这个建造者模式,学会了真的是可以用起来,是你的代码更加优雅的。

  1. 什么是建造者模式

当我们想要创建一个复杂对象的时候,我们通常都是把他的属性,都准备好,然后利用全参数构造把它创建出来,但是,这有一个弊端: 如果我想要一个对象,它没必要那么多属性呢,只需要两个,三个,那聪明的你肯定会想到再来个重载的构造呗!

回答正确,但是,需求总是无限,你准备按照排列组合,把所有的构造方法都写出来吗,那必然是有点拉跨的。这时候,就可以用到建造者模式。

在建造者模式中,主要有以下四个角色:

  1. 产品(Product):最终要构建的复杂对象,通常包含多个组成部分,如汽车包含引擎、轮胎等。
  2. 抽象建造者(Builder):定义构建产品的接口,规定了构建产品的各个步骤。
  3. 具体建造者(Concrete Builder):实现Builder接口,提供构建产品的具体实现,并负责具体产品的构建过程。具体建造者通常会提供一个获取最终构建结果的方法。
  4. 指挥者(Director):负责安排已有模块的构建步骤,指导具体建造者构建出产品。它不依赖于具体的建造者。

建造者模式的主要优点如下:

  • 易于解耦:由于建造者独立于具体产品类,因此容易扩展和修改具体产品类。
  • 易于控制细节风险:由于建造者之间独立,因此可以很方便地替换具体建造者或修改具体建造者的实现,而不会对其他模块产生影响。
  • 易于扩展:由于指挥者类针对抽象建造者编程,增加新的具体建造者无需修改原有类库的代码,符合"开闭原则"。

在实际应用中,例如,当需要创建一个复杂对象,且这个对象内部有很多属性,且这些属性之间存在一定的构建顺序时,就可以使用建造者模式来简化对象的创建过程。

  1. 如何使用建造者模式

java 复制代码
public class Person {

    private final String name;
    private final int age;
    private final String car;
    private final String house;

    public Person (Builder builder) {
        this.name = builder.name;
        this.age = builder.age;
        this.car = builder.car;
        this.house = builder.house;
    }

    public static class Builder {
        private String name;
        private int age;
        private String car;
        private String house;

        public Builder setName(String name) {
            this.name = name;
            return this;
        }

        public Builder setAge(int age) {
            this.age = age;
            return this;
        }

        public Builder setCar(String car) {
            this.car = car;
            return this;
        }

        public Builder setHouse(String house) {
            this.house = house;
            return this;
        }

        public Person build() {
            return new Person(this);
        }
    }
}

3. 我们用建造者模式来创建对象,看看有啥好处

我们来创建一个马云,身价过亿,车,房都是好的

然后再创建一个felix, 不过我就比较特别,我甚至都没车没房,但是我们用了建造者模式,也不需要再写一个重载方法了,代码如下:

java 复制代码
public static void main(String[] args) {
    Person jackMa = new Builder().setName("马云")
    .setAge(62)
    .setCar("劳斯莱斯")
    .setHouse("汤臣一品")
    .build();


    Person felix = new Builder().setName("Felix")
    .setAge(28)
    .build();


    System.out.println(jackMa);
    System.out.println(felix);
}

//输出结果
D:\jdk8\bin\java.exe "-javaagent:D:\software\IntelliJ IDEA 2020.3.3\lib\idea_rt.jar=63808:D:\software\IntelliJ IDEA 2020.3.3\bin" -Dfile.encoding=UTF-8 -classpath D:\jdk8\jre\lib\charsets.jar;D:\jdk8\jre\lib\ext\access-bridge-64.jar;D:\jdk8\jre\lib\ext\cldrdata.jar;D:\jdk8\jre\lib\ext\dnsns.jar;D:\jdk8\jre\lib\ext\jaccess.jar;D:\jdk8\jre\lib\ext\jfxrt.jar;D:\jdk8\jre\lib\ext\localedata.jar;D:\jdk8\jre\lib\ext\nashorn.jar;D:\jdk8\jre\lib\ext\sunec.jar;D:\jdk8\jre\lib\ext\sunjce_provider.jar;D:\jdk8\jre\lib\ext\sunmscapi.jar;D:\jdk8\jre\lib\ext\sunpkcs11.jar;D:\jdk8\jre\lib\ext\zipfs.jar;D:\jdk8\jre\lib\jce.jar;D:\jdk8\jre\lib\jfr.jar;D:\jdk8\jre\lib\jfxswt.jar;D:\jdk8\jre\lib\jsse.jar;D:\jdk8\jre\lib\management-agent.jar;D:\jdk8\jre\lib\resources.jar;D:\jdk8\jre\lib\rt.jar;D:\code\felix\out\production\patterns Person
Person{name='马云', age=62, car='劳斯莱斯', house='汤臣一品'}
Person{name='Felix', age=28, car='null', house='null'}

哈哈哈哈,这个例子是不是很生动形象,就是有点小扎心。

好的,今天就是给大家带来的建造者模式的讲解。

相关推荐
李慕婉学姐29 分钟前
【开题答辩过程】以《基于JAVA的校园即时配送系统的设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
java·开发语言·数据库
奋进的芋圆2 小时前
Java 延时任务实现方案详解(适用于 Spring Boot 3)
java·spring boot·redis·rabbitmq
sxlishaobin2 小时前
设计模式之桥接模式
java·设计模式·桥接模式
model20052 小时前
alibaba linux3 系统盘网站迁移数据盘
java·服务器·前端
荒诞硬汉3 小时前
JavaBean相关补充
java·开发语言
提笔忘字的帝国3 小时前
【教程】macOS 如何完全卸载 Java 开发环境
java·开发语言·macos
2501_941882483 小时前
从灰度发布到流量切分的互联网工程语法控制与多语言实现实践思路随笔分享
java·开发语言
華勳全栈4 小时前
两天开发完成智能体平台
java·spring·go
alonewolf_994 小时前
Spring MVC重点功能底层源码深度解析
java·spring·mvc
沛沛老爹4 小时前
Java泛型擦除:原理、实践与应对策略
java·开发语言·人工智能·企业开发·发展趋势·技术原理