【设计模式 】| 建造者源码学习与实践

简介: 为什么要用建造者模式?在我们看来他和工厂模式的目的是一样的,就是为了获取对象。

前言

为什么要用建造者模式?在我们看来他和工厂模式的目的是一样的,就是为了获取对象。下面我们进一步来了解建造者模式是什么,以及他在我们业务开发中的使用场景。

纲要

网络异常,图片无法展示
|

什么是建造者模式?

建造者模式(Builder Pattern):将复杂对象的构造与其表示分离,以便同一构造过程可以创建不同的表示。

优缺点

网络异常,图片无法展示
|

四大主要角色

网络异常,图片无法展示
|

为什么要用建造者模式?

从两点来考虑

  1. 分阶段、分步骤的方法更适合多次运算结果类创建场景
  2. 不需要关心特定类型的建造者的具体算法实现

封装的变化

  1. 建造器的数量与具体实现
  2. 建造器内部创建多个属性
  3. 建造器的步骤

常用场景

网络异常,图片无法展示
|

实现Bean对象的构建

//建造者的抽象基类(接口)
public interface Builder<T> {
    T  build();
}
//最终构建的对象
public class User {
    private boolean isRef;
    private Object name;
    private String cardId;
    public Object getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "User{" +
            "name='" + name + '\'' +
            ", cardId='" + cardId + '\'' +
            '}';
    }
    private User(BuilderImpl builder){
        this.name = builder.name;
        this.cardId = builder.cardId;
    }
    private static BuilderImpl builder(){
        return new BuilderImpl();
    }
    // Builder 类的具体实现类 && 指挥者
    private static class BuilderImpl implements Builder<User> {
        private Object name;
        private String cardId;
        private boolean isRef;
        private BuilderImpl name(Object name){
            this.name = name;
            return this;
        }
        private BuilderImpl cardId(String cardId){
            this.cardId = cardId;
            return this;
        }
        private BuilderImpl isRef(boolean isRef){
            this.isRef = isRef;
            return this;
        }
        //指挥者,得到一个新的User对象
        @Override
        public User build(){
            if (!this.isRef){
                if (this.name == null || this.cardId == null){
                    throw new NullPointerException();
                }
            }else {
                if (!(this.name instanceof String)){
                    throw new IllegalArgumentException("name必须为String类型");
                }
            }
            return new User(this);
        }
    }
    public static void main(String[] args) {
        User u = User.builder().isRef(true).name(213).cardId("cardId").build();
        System.out.println(u);
    }
}

上面的实现逻辑,就是Lombok注释中,@Builder的大概实现,我们可以通过set方法设置建造者的变量值,自由组合来完成一个新的对象,

在结尾的build()方法中集中进行数据的校验。

源码学习案例

  1. JDK 类库中的 Appendable 接口
  2. StringBuilder

建造者的抽象基类(接口)

public interface Appendable {
        Appendable append(CharSequence csq) throws IOException;
        Appendable append(CharSequence csq, int start, int end) throws IOException;
        Appendable append(char c) throws IOException;
        }

Builder 类的具体实现类

abstract class AbstractStringBuilder implements Appendable, CharSequence {
    AbstractStringBuilder() {
    }
    AbstractStringBuilder(int capacity) {
        value = new char[capacity];
    }
    // Documentation in subclasses because of synchro difference
    @Override
    public AbstractStringBuilder append(CharSequence s) {
        if (s == null)
            return appendNull();
        if (s instanceof String)
            return this.append((String)s);
        if (s instanceof AbstractStringBuilder)
            return this.append((AbstractStringBuilder)s);
        return this.append(s, 0, s.length());
    }
    @Override
    public AbstractStringBuilder append(CharSequence s, int start, int end) {
        if (s == null)
            s = "null";
        if ((start < 0) || (start > end) || (end > s.length()))
            throw new IndexOutOfBoundsException(
                "start " + start + ", end " + end + ", s.length() "
                + s.length());
        int len = end - start;
        ensureCapacityInternal(count + len);
        for (int i = start, j = count; i < end; i++, j++)
            value[j] = s.charAt(i);
        count += len;
        return this;
    }
    @Override
    public AbstractStringBuilder append(char c) {
        ensureCapacityInternal(count + 1);
        value[count++] = c;
        return this;
    }
}

指挥者与具体的建造者

public final class StringBuilder
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
{
    public StringBuilder() {
        super(16);
    }
    public StringBuilder(int capacity) {
        super(capacity);
    }
    public StringBuilder(String str) {
        super(str.length() + 16);
        append(str);
    }
    @Override
    public StringBuilder append(Object obj) {
        return append(String.valueOf(obj));
    }
    @Override
    public StringBuilder append(String str) {
        super.append(str);
        return this;
    }
}

通过上面的代码可以看出他们之间的关系

  1. Appendable作为基类,提供三个方法
  2. AbstractStringBuilder实现了三个方法
  3. 在StringBuilder中继承了AbstractStringBuilder类,重写父类的方法,履行指导者的作用,调用append方法,返回一个StringBuilder对象

与工厂模式的区别

工厂模式:根据用户选择,来制作不同的食物,汉堡、面条、包子。

建造者模式:根据用户选择,来制作,加什么材料的汉堡。

  1. 工厂是生产某个配件,而建造者是整合配件
  2. 建造者注重步骤,按照步骤组装完整
  3. 工厂注重于创建不同对象

总结

建造者模式在我们业务开发中还是经常使用的, 他帮助我们自由组合创建对象,提高了灵活性,但是增加了代码量。

相关文章
|
1月前
|
设计模式 算法 搜索推荐
后端开发中的设计模式应用与实践
在软件开发的广袤天地中,后端技术如同构筑高楼大厦的钢筋水泥,支撑起整个应用程序的骨架。本文旨在通过深入浅出的方式,探讨后端开发领域内不可或缺的设计模式,这些模式犹如精雕细琢的工具箱,能够助力开发者打造出既健壮又灵活的系统架构。从单例模式到工厂模式,从观察者模式到策略模式,每一种设计模式都蕴含着深刻的哲理与实践价值,它们不仅仅是代码的组织方式,更是解决复杂问题的智慧结晶。
|
2月前
|
设计模式 算法 测试技术
PHP中的设计模式:策略模式的应用与实践
在软件开发的浩瀚海洋中,设计模式如同灯塔,指引着开发者们避开重复造轮子的暗礁,驶向高效、可维护的代码彼岸。今天,我们将聚焦于PHP领域中的一种重要设计模式——策略模式,探讨其原理、应用及最佳实践,揭示如何通过策略模式赋予PHP应用灵活多变的业务逻辑处理能力,让代码之美在策略的变换中熠熠生辉。
|
28天前
|
设计模式 API 持续交付
深入理解微服务架构:设计模式与实践
【10月更文挑战第19天】介绍了微服务架构的核心概念、设计模式及最佳实践。文章详细探讨了微服务的独立性、轻量级通信和业务能力,并介绍了聚合器、链式和发布/订阅等设计模式。同时,文章还分享了实施微服务的最佳实践,如定义清晰的服务边界、使用API网关和服务发现机制,以及面临的挑战和职业心得。
|
1月前
|
设计模式 存储 数据库连接
PHP中的设计模式:单例模式的深入解析与实践
在PHP开发中,设计模式是提高代码可维护性、扩展性和复用性的关键技术之一。本文将通过探讨单例模式,一种最常用的设计模式,来揭示其在PHP中的应用及优势。单例模式确保一个类仅有一个实例,并提供一个全局访问点。通过实际案例,我们将展示如何在PHP项目中有效实现单例模式,以及如何利用这一模式优化资源配置和管理。无论是PHP初学者还是经验丰富的开发者,都能从本文中获得有价值的见解和技巧,进而提升自己的编程实践。
|
1月前
|
设计模式 算法 PHP
PHP中的设计模式:策略模式的深入解析与实践
【10月更文挑战第9天】 策略模式是一种行为设计模式,它允许在运行时选择算法的行为。在PHP开发中,通过使用策略模式,我们可以轻松切换算法或逻辑处理方式而无需修改现有代码结构。本文将深入探讨策略模式的定义、结构以及如何在PHP中实现该模式,并通过实际案例展示其应用价值和优势。
30 1
|
1月前
|
设计模式 算法 PHP
PHP中的设计模式:策略模式的深入解析与实践
在PHP开发中,设计模式是提高代码可读性、可维护性和扩展性的重要工具。本文将深入探讨策略模式这一行为型设计模式,通过分析其定义、结构、使用场景以及在PHP中的实际应用,帮助开发者更好地理解和运用策略模式来优化自己的项目。不同于传统摘要的简洁概述,本文摘要部分将详细阐述策略模式的核心理念和在PHP中的实现方法,为读者提供清晰的指引。
|
1月前
|
设计模式 存储 测试技术
PHP中的设计模式:单例模式的深入解析与实践
在PHP开发领域,设计模式是解决常见问题的最佳实践。本文将深入探讨单例模式,一种确保类只有一个实例的设计模式,并提供实际应用示例。我们将从单例模式的基本概念讲起,通过实际案例展示如何在PHP中实现单例模式,以及它在不同场景下的应用和优势。最后,我们会探讨单例模式的优缺点,帮助开发者在实际项目中做出明智的选择。
|
1月前
|
设计模式 算法 PHP
PHP中的设计模式:策略模式的深入解析与实践
策略模式是一种行为型设计模式,用于定义一系列算法,将每种算法都封装起来,并使它们可以互换。本文将探讨如何在PHP中实现策略模式,以及如何利用它来提高代码的灵活性和可维护性。通过具体示例,我们将看到策略模式在处理复杂业务逻辑时的优势,从而帮助开发者编写出更加清晰、易于扩展的代码。
|
1月前
|
设计模式 SQL 安全
PHP中的设计模式:单例模式的深入探索与实践在PHP开发领域,设计模式是解决常见问题的高效方案集合。它们不是具体的代码,而是一种编码和设计经验的总结。单例模式作为设计模式中的一种,确保了一个类仅有一个实例,并提供一个全局访问点。本文将深入探讨单例模式的基本概念、实现方式及其在PHP中的应用。
单例模式在PHP中的应用广泛,尤其在处理数据库连接、日志记录等场景时,能显著提高资源利用率和执行效率。本文从单例模式的定义出发,详细解释了其在PHP中的不同实现方法,并探讨了使用单例模式的优势与注意事项。通过对示例代码的分析,读者将能够理解如何在PHP项目中有效应用单例模式。
|
1月前
|
设计模式 算法 PHP
PHP中的设计模式:策略模式的深入解析与实践
在软件开发的广袤领域中,PHP以其灵活性和广泛的应用场景占据了一席之地。本文聚焦于PHP中的一个核心概念——设计模式,特别是策略模式。策略模式作为一种行为型设计模式,允许在运行时选择算法或操作的具体实现,为软件设计带来了极大的灵活性。本文将深入探讨策略模式的基本原理、应用场景以及在PHP中的具体实现方式,旨在帮助开发者更好地理解和运用这一设计模式,提升代码的可维护性和扩展性。
18 2
下一篇
无影云桌面