【设计模式】-创建型模式-第2章第3讲-【建造者模式】

简介: 【设计模式】-创建型模式-第2章第3讲-【建造者模式】

目录

场景需求

1、建造者模式中包含以下4个类

2、实际代码示例

2.1、具体产品(Product)类

2.2、抽象建造者(Builder )

2.3、具体建造者(ConcreteBuilder )

2.4、指挥者(Director)

3、简化的建造者模式

4、拥有方法链的匿名建造者

4.1、这种情况下,使用我们的建造者模式避免这种情况是个不错的实践。

4.2、JDK源码中典型的应用场景

5、建造者模式的优缺点

5.1、优点

5.2、缺点

场景需求

墨菲定律中提道:任何事都没有表面看起来的那么简单。无论在现实生活中还是在代码世界中,都存在一些复杂的对象,他们由多个部分组成,每个部分各具功能,协同运作。比如手机包含摄像头、CPU、电池等各种零部件。对于大部分用户而言,无须知道部件之间的组装细节,也几乎不会单独使用某个零部件,而是使用一部完整的手机。如果需要详细关注一个产品部件的生产、安装步骤,可以选择建造者模式对其进行设计与描述,将部件和其组装过程分开,分步创建一个复杂的对象。由于组装部件的过程复杂,因此,装配过程被分离到一个称作建造者的对象里,建造者返回给上层一个完整产品,而无需关心该产品的构建细节,这就是建造者模式的核心思想。

建造者模式(Builder Pattern)也叫做生成器模式。

将复杂对象的构建与表示分离,同构建过程,创建不同表示。隐藏复杂对象创建过程,并把这个过程加以抽象(通过子类继承或者重载的方式,动态的创建具有复合属性的对象)。

1、建造者模式中包含以下4个类

1)Product (产品类):需要为其构建对象的类,是具有不同表现形式的复杂或复合对象。

2)Builder (抽象建造者类):用于声明构建产品类的组成部分的抽象类或接口。它的作用是仅公开构建产品类的功能,隐藏产品类的其他功能;将产品类与构建产品类的更高级的类分离开。

3)ConcreteBuilder(具体建造者类):用于实现抽象建造者类接口中声明的方法。除此之外,它还通过 getResult 方法返回构建好的产品类。

4)Director(导演类):用于指导如何构建对象的类。在建造者模式的某些变体中,导演类已被移除,其角色被客户端或抽象建造者类所代替。

建造者模式通用类图 如下 图1-1:

74428621831943e9a7496a11322a4044.png


图 1-1

2、实际代码示例

这里我就从4个角色的具体代码示例,直观的去看看建造者模式的实现方式。

2.1、具体产品(Product)类

Product 产品类,一般是多个部件组成的复杂对象,由具体建造者来创建其各个零部件。

通用代码如下:

package com.zhaoyanfei.designpattern.buliderpattern;
 
/**
 * 具体产品类(可以是一个复杂对象)
 * @author zhaoYanFei
 *
 */
public class Product {
 
    
    
    public void doSomething() {
        System.out.println("doSomething is done.");
    }
}

2.2、抽象建造者(Builder )

Builder 抽象建造者,包含创建产品各个子部件的抽象方法以及返回复杂产品的方法。

通用代码如下:

package com.zhaoyanfei.designpattern.buliderpattern;
/**
 * 抽象建造者
 * @author zhaoYanFei
 *
 */
public abstract class Builder {
 
    /**
     * 设置不同的模块组装产品
     */
    public abstract void setPart();
    /**
     * 构建产品
     * @return
     */
    public abstract Product builderProduct();
    
}

2.3、具体建造者(ConcreteBuilder )

ConcreteBuilder 具体建造者,实现抽象 Builder 定义的所有方法,并且返回一个装配好的对象。

通用代码如下:

    package com.zhaoyanfei.designpattern.buliderpattern;
    /**
     * 具体建造者
     * @author zhaoYanFei
     *
     */
    public class ConcreteBuilder extends Builder {
     
        private Product product = new Product();
        
        @Override
        public void setPart() {
            // TODO 完成产品的组装逻辑,包括组装顺序,不同方法的组合等等
     
        }
     
        @Override
        public Product builderProduct() {
            // TODO Auto-generated method stub
            //返回创建好的实体类
            return product;
        }
     
    }

2.4、指挥者(Director)

Director 指挥者,负责安排已有模块的顺序,然后调用 Builder 建造产品。

通用代码如下:

    package com.zhaoyanfei.designpattern.buliderpattern;
    /**
     * 导演类,也叫指挥者,负责调度产品构建的方法
     * @author zhaoYanFei
     *
     */
    public class Director {
     
        /**
         * 不同的产品由不同的方法实现
         * @return
         */
        public Product getProduct(){
            ConcreteBuilder concreteBuilder = new ConcreteBuilder();
            concreteBuilder.setPart();
            return concreteBuilder.builderProduct();
        }
    }

3、简化的建造者模式

在建造者模式的某些实现方式中可以移除导演类。比如导演类的封装逻辑很简单,这种情况下,可以不需要导演类。简化的类图构建者模式如下图3-1:

3f9e91fdee5f42f792c0ce6ff91137ab.png

这里可以看到我们只是将导演类中实现的代码移动到了客户端,但是当抽象基类和产品类太过复杂,或者需要使用建造者类从数据流中构建对象时,我们不建议这样简化修改。

4、拥有方法链的匿名建造者

构建来自相同类,但是具有不同表现形式的对象的最直接方法就是利用 Java 的多态,构建多个不同入参的构造函数,按照不同的场景进行不同的实例化操作。

4.1、这种情况下,使用我们的建造者模式避免这种情况是个不错的实践。

在 《Effective Java》一书中,Joshua Bloch 建议使用内部建造者类和方法链来代替多个构造函数。

方法链是指通过特定方法返回当前对象(this)的一种技术。通过这种技术,可以以链的形式调用方法。

注:方法链的一个限制是,只能用在不需要返回其他值的方法上,因为你需要返回 self 对象。

    @Override
        public Builder setPart() {
            // TODO 完成产品的组装逻辑,包括组装顺序,不同方法的组合等等
            product.setAge(20);
            return this;
        }

4.2、JDK源码中典型的应用场景

dbf896a45acf41cf838fcc94f3d2f8ce.png

StringBuilder 继承了 AbstractStringBuilder 类

2de303c016814d49a4a4c8312edc604c.png

而 AbstractStringBuilder 实现了 Appendable 接口

可以看到 Appendable 中声明了三个追加的方法。

 
package java.lang;
 
import java.io.IOException;
 
/**
 * @since 1.5
 */
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;
}

StringBuilder 中实现的 append 方法:

public final class StringBuilder
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
{
    @Override
    public StringBuilder append(String str) {
        super.append(str);
        return this;
    }
}

5、建造者模式的优缺点

5.1、优点

1、封装性,在建造者模式中,调用方不必知道产品内部组成的细节,将一个复杂对象的构建与它的表示分离,使得相同的创建过程可以创建不同的产品对象。

2、扩展性,每个具体建造者都相互独立,替换具体建造者或新增具体建造者都很便捷。

3、更关注"由零件一步一步地组装出产品对象" 。将复杂产品的创建步骤拆分到不同的方法中,使得创建过程更加清晰。

5.2、缺点

1、建造者模式所创建的产品对象一般组成部分相似,如果产品的内部变化复杂,需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大。

2、如果产品内部结构发生变化,建造者也要相应修改,有较大的维护成本。

结尾:其实很多模式,我们在应用过程中,并不是单独的应用某种设计模式,有时候会涉及到多种模式复合使用。设计模式其实是我们的一种编程思维,是我们处理问题的方式而已。

个人建议,想系统学习某一个知识点儿,可以给自己制定一个目标,比如 23 种设计模式,我就每天学习一种设计模式,多了不学。如果你能坚持下来,其实这个过程本身就已经很厉害了。

下一节,我将带领大家了解原型模式。

相关文章
|
2月前
|
设计模式 算法
设计模式--建造者模式 builder
这篇文章通过一个电脑购买的例子,详细解释了建造者模式的四个角色(产品类、抽象构建者、实体构建类和指导者类),并提供了相应的代码实现,阐述了建造者模式在设计复杂对象时的应用和优势。
设计模式--建造者模式 builder
|
4天前
|
设计模式 JavaScript Java
Java设计模式:建造者模式详解
建造者模式是一种创建型设计模式,通过将复杂对象的构建过程与表示分离,使得相同的构建过程可以创建不同的表示。本文详细介绍了建造者模式的原理、背景、应用场景及实际Demo,帮助读者更好地理解和应用这一模式。
|
2月前
|
设计模式 算法 Java
Java设计模式-建造者模式(6)
Java设计模式-建造者模式(6)
|
3月前
|
设计模式 存储 负载均衡
【五】设计模式~~~创建型模式~~~单例模式(Java)
文章详细介绍了单例模式(Singleton Pattern),这是一种确保一个类只有一个实例,并提供全局访问点的设计模式。文中通过Windows任务管理器的例子阐述了单例模式的动机,解释了如何通过私有构造函数、静态私有成员变量和公有静态方法实现单例模式。接着,通过负载均衡器的案例展示了单例模式的应用,并讨论了单例模式的优点、缺点以及适用场景。最后,文章还探讨了饿汉式和懒汉式单例的实现方式及其比较。
【五】设计模式~~~创建型模式~~~单例模式(Java)
|
3月前
|
设计模式 XML 存储
【三】设计模式~~~创建型模式~~~抽象工厂模式(Java)
文章详细介绍了抽象工厂模式,这是一种创建型设计模式,用于提供一个接口以创建一系列相关或相互依赖的对象,而不指定它们具体的类。通过代码示例和结构图,文章展示了抽象工厂模式的动机、定义、结构、优点、缺点以及适用场景,并探讨了如何通过配置文件和反射机制实现工厂的动态创建。
【三】设计模式~~~创建型模式~~~抽象工厂模式(Java)
|
3月前
|
设计模式 XML 存储
【二】设计模式~~~创建型模式~~~工厂方法模式(Java)
文章详细介绍了工厂方法模式(Factory Method Pattern),这是一种创建型设计模式,用于将对象的创建过程委托给多个工厂子类中的某一个,以实现对象创建的封装和扩展性。文章通过日志记录器的实例,展示了工厂方法模式的结构、角色、时序图、代码实现、优点、缺点以及适用环境,并探讨了如何通过配置文件和Java反射机制实现工厂的动态创建。
【二】设计模式~~~创建型模式~~~工厂方法模式(Java)
|
3月前
|
设计模式 XML Java
【一】设计模式~~~创建型模式~~~简单工厂模式(Java)
文章详细介绍了简单工厂模式(Simple Factory Pattern),这是一种创建型设计模式,用于根据输入参数的不同返回不同类的实例,而客户端不需要知道具体类名。文章通过图表类的实例,展示了简单工厂模式的结构、时序图、代码实现、优缺点以及适用环境,并提供了Java代码示例和扩展应用,如通过配置文件读取参数来实现对象的创建。
【一】设计模式~~~创建型模式~~~简单工厂模式(Java)
|
3月前
|
设计模式 存储 XML
[设计模式]创建型模式-抽象工厂模式
[设计模式]创建型模式-抽象工厂模式
|
3月前
|
设计模式 测试技术 Go
[设计模式]创建型模式-简单工厂模式
[设计模式]创建型模式-简单工厂模式
|
3月前
|
设计模式 XML 存储
【四】设计模式~~~创建型模式~~~建造者模式(Java)
文章详细介绍了建造者模式(Builder Pattern),这是一种创建型设计模式,用于将复杂对象的构建与其表示分离,允许分步骤创建一个复杂的对象而无需指定其内部的具体构造细节。通过定义抽象建造者、具体建造者、指挥者和产品角色,建造者模式允许通过相同的构建过程创建不同的产品表示,提高了系统的灵活性和扩展性。

热门文章

最新文章

  • 1
    C++一分钟之-设计模式:工厂模式与抽象工厂
    42
  • 2
    《手把手教你》系列基础篇(九十四)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-下篇(详解教程)
    46
  • 3
    C++一分钟之-C++中的设计模式:单例模式
    53
  • 4
    《手把手教你》系列基础篇(九十三)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-上篇(详解教程)
    37
  • 5
    《手把手教你》系列基础篇(九十二)-java+ selenium自动化测试-框架设计基础-POM设计模式简介(详解教程)
    61
  • 6
    Java面试题:结合设计模式与并发工具包实现高效缓存;多线程与内存管理优化实践;并发框架与设计模式在复杂系统中的应用
    56
  • 7
    Java面试题:设计模式在并发编程中的创新应用,Java内存管理与多线程工具类的综合应用,Java并发工具包与并发框架的创新应用
    40
  • 8
    Java面试题:如何使用设计模式优化多线程环境下的资源管理?Java内存模型与并发工具类的协同工作,描述ForkJoinPool的工作机制,并解释其在并行计算中的优势。如何根据任务特性调整线程池参数
    49
  • 9
    Java面试题:请列举三种常用的设计模式,并分别给出在Java中的应用场景?请分析Java内存管理中的主要问题,并提出相应的优化策略?请简述Java多线程编程中的常见问题,并给出解决方案
    105
  • 10
    Java面试题:设计模式如单例模式、工厂模式、观察者模式等在多线程环境下线程安全问题,Java内存模型定义了线程如何与内存交互,包括原子性、可见性、有序性,并发框架提供了更高层次的并发任务处理能力
    75