【设计模式】创建型设计模式之 建造者模式

文章目录

  • 一、介绍
      • 定义
      • [UML 类图](#UML 类图)
  • [二、用法1 简化复杂对象具体构建过程](#二、用法1 简化复杂对象具体构建过程)
      • [省略抽象的 Builder 类](#省略抽象的 Builder 类)
      • [省略 Director 类](#省略 Director 类)
  • [三、用法2 控制对象构造方法、限制参数关系](#三、用法2 控制对象构造方法、限制参数关系)
      • [Guava 中使用建造者模式构建 cache 来进行参数校验](#Guava 中使用建造者模式构建 cache 来进行参数校验)

一、介绍

定义

建造者模式,将一个复杂的对象的构建过程与表示分离,使得同样的构建过程可以构建不同的结果。

UML 类图

  1. 抽象建造者类(Builder):这个接口规定要实现复杂对象的哪些部分的创建,并不涉及具体的部件对象的创建。
  2. 具体建造者类(ConcreteBuilder):实现 Builder 接口,完成复杂产品的各个部件的具体创建方法。在构造过程完成后,提供一个方法,返回创建好的负责产品对象。
  3. 产品类(Product):要创建的复杂对象 (包含多个组成部件).
  4. 指挥者类(Director):调用具体建造者来创建复杂对象的各个部分,在指导者中不涉及具体产品的信息,只负责保证对象各部分完整创建或按某种顺序创建(客户端一般只需要与指挥者进行交互)。

二、用法1 简化复杂对象具体构建过程

java 复制代码
public class Bike {

    //车架
    private String frame;

    //座椅
    private String seat;

    public String getFrame() {
        return frame;
    }

    public void setFrame(String frame) {
        this.frame = frame;
    }

    public String getSeat() {
        return seat;
    }

    public void setSeat(String seat) {
        this.seat = seat;
    }
}
java 复制代码
public abstract class Builder {

    protected Bike mBike = new Bike();

    public abstract void buildFrame();
    public abstract void buildSeat();
    public abstract Bike createBike();
}

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

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

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

public class MobikeBuilder 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;

    public Director(Builder builder) {
        this.mBuilder = builder;
    }

    public Bike construct() {
        mBuilder.buildFrame();
        mBuilder.buildSeat();
        return mBuilder.createBike();
    }
}
java 复制代码
public class Client {

    public static void main(String[] args) {
        showBike(new HelloBuilder());
        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());
    }
}

省略抽象的 Builder 类

如果系统中只需要一个具体的建造者,可以省略抽象建造者

省略 Director 类

如果只有一个具体建造者,并且简化了抽象建造者,那么可以省略掉指导者。让建造者直接扮演指导者。

三、用法2 控制对象构造方法、限制参数关系

建造者模式除了用来分离复杂对象的构建过程,还可以在构建对象的同时用来控制对象的构造方法,限制对象的构建参数关系。

使用场景

  1. 场景 1 类的构造方法过长,降低了代码可读性容易搞错参数。
  2. 场景 2 使用 setter 方法优化场景 1,但是这样会导致遗漏对象的必填属性并且无法实现前后关联属性的设置。
java 复制代码
public class ResourcePoolConfig{
    private String name;
    private int maxTotal;
    private int maxIdle;
    private int minIdle;
    
    //如果builder是内部类,这里就可以使用private修饰
    public ResourcePoolConfig (Builder builder){
        this.name=builder.name;
        this.maxTotal=builder.maxTotal;
        this.maxIdle=builder.maxIdle;
        this.minIdle=builder.minIdle;
    }
}
java 复制代码
public class Builder{
    private static final int DEFAULT_MAX_TOTAL=9;
    private String name;
    private int maxTotal;
    //其他字段省略

    public ResourcePoolConfig build(){
        //可以写校验逻辑
        return new ResourcePoolConfig(this);
    }
    
    public Builder setMaxTotal(int maxTotal){
        //校验
        if(maxTotal<0){
            throw new RuntimeException();
        }
        this.maxTotal=maxTotal;
    }
    
}

Guava 中使用建造者模式构建 cache 来进行参数校验

Guava本地缓存框架是Google的Guava库提供的一种高性能、线程安全的本地缓存实现。它旨在帮助Java开发者有效地管理和存储数据在内存中,从而加速数据访问速度并减轻对底层数据存储系统的压力。Guava Cache具有丰富的特性和灵活性,使其成为处理高并发和高性能需求场景下的理想选择。下面是一些关键特性和使用方法的概述:

主要特性:

  1. 自动加载(Loading Cache): Guava允许你定义一个CacheLoader,当缓存中没有请求的键对应的值时,自动调用加载数据的方法并插入到缓存中。这样可以实现懒加载,并且保持代码的简洁性。
  2. 缓存过期: 支持基于时间(如访问后多久过期、写入后多久过期)或基于大小(如缓存容量达到上限后开始移除旧的条目)的过期策略,自动管理缓存项的有效性,避免内存泄漏。
  3. 统计信息: 提供丰富的统计信息,比如命中率、平均加载时间等,帮助监控和优化缓存性能。
  4. 软引用和弱引用: Guava Cache允许使用软引用或弱引用存储缓存项,这样当JVM内存紧张时,这些引用可以被垃圾收集器回收,以避免内存溢出。
  5. 并发支持: 内部实现高度并发安全,利用锁和其他同步机制确保在多线程环境下的正确性和高效性。
  6. 可自定义的缓存行为: 通过CacheBuilder,你可以自定义缓存的各种行为,比如缓存过期策略、最大容量、加载机制、统计开启与否等。

guava 中就通过建造者模式来解决了构造参数过长的问题,因为如果先构造无参对象再通过 SET 赋值参数则无法实现必要的参数校验;

Google Guava 中构建内存缓存的案例如下;

java 复制代码
public class CacheDemo{
    public static void main(String[] args){
        Cache<String,String> cache = CacheBuilder.newBuilder()
                .initialCapacity(100)
                .maximumSize(100)
                .expireAfterWrite(10,TimeUnit.MINUTES)
                .build();
        cache.put("key1","value1");
        String value = cache.getIfPresent("key1");
        System.out.println(value);
    }
}
相关推荐
骄马之死1 小时前
SpringMVC + SpringBoot 核心知识点总结
java·spring boot·后端
zhengfei6111 小时前
第3章 Agent 类型分类与设计模式
设计模式
刀法如飞2 小时前
一文搞懂DDD 领域驱动设计思想原理
设计模式·架构·代码规范
郑洁文2 小时前
基于Spring Boot的流浪动物救助网站
java·spring boot·后端·毕设·流浪动物救助
螺丝钉code3 小时前
JAVA项目 Claude code CLAUDE.md 到底应该怎么写
java·人工智能·claude code
摇滚侠4 小时前
Maven 入门+高深 单一架构案例 54-59
java·架构·maven·intellij-idea
VidDown4 小时前
Webhook 调试器:让第三方回调“原形毕露”
java·开发语言·javascript·编辑器·postman
折哥的程序人生 · 物流技术专研5 小时前
Java 23 种设计模式:从踩坑到精通 | 原型模式 —— 克隆对象,深拷贝与浅拷贝的坑你踩过吗?
java·设计模式·架构·原型模式·单一职责原则
装不满的克莱因瓶5 小时前
基于 OpenResty 扩展开发实现动态服务注册与发现能力
java·开发语言·架构·openresty