java设计模式---建造者模式

简介: java设计模式---建造者模式

一,建造者模式

1,基本概念

客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建出不同的产品对象。


每一个具体建造者相对独立,而与其他的具体建造者无关,因此可以很方便的替换具体建造者或增加新的具体建造者,用户使用不同的具体的建造者可以得到不同的产品对象。


2,建造者模式使用场景

一个对象有非常复杂的内部结构,比如说很多属性等

想把对象的创建和使用分离


3,建造者优缺点

3.1,优点

封装性好,创建和使用分离

扩展性好,建造类之间独立,在一定程度上解耦


3.2,缺点

会产生多余的Builder对象


产品内部发生变化,建造者也需要修改,成本可能会随着业务场景的改变而改变


4,建造者模式四个角色

Product :产品角色,一个具体的产品对象

Builder:抽象的建造者,创建一个Product对象的各个部件的指定的接口和抽象类

ConcreateBuilder:具体的构建者,实心接口,构建和装配各个部件

Director:指挥者,构建一个使用Builder接口的对象,主要是创建一个复杂的对象。主要有两个作用,一个是隔离客户端与对象的生产的过程,而是负责控制产品对象的生产过程

37e5524f44c44ead95acf57f9946b553.png


5,建造者模式和工厂模式区别

建造者模式更加注重于方法的调用顺序,工厂模式更加的注重于创建产品


建造者模式创建产品的复杂度可能相对较高,工厂模式创建出来的产品都是一个模样


建造者模式需要将产品创建出来,并且需要知道是由那些组件构成,而工厂模式注重的只是将这个对象创建出来


二,代码实现

1,需求如下

需求如下,有一个视频的作品资源类,然后需要将这个视频作品发布到某一个平台,然后里面的每一个属性都非常复杂,比如说会有一个视频,作品名称,视频的ppt,视频的标题,视频的答案等。然后在获取到视频作品的全部信息之后,会通过一个平台的管理员将这些内容合并,然后做一个审核等操作,审核通过的话将这个视频发布到该平台。


2,需求分析

那么这个视频就相当于一个 Product 的一个产品角色,由于内部属性较复杂,那么就需要通过这种构建者的方式实现,这个平台的管理员就类似与这个指挥者,需要通过这个管理员来操作这个builder类


3,代码实现

1,产品角色,视频资源类Course类

package com.zhs.responsibility;
/**
 * @author zhenghuisheng
 * @date : 2022/9/16
 * 课程类
 */
public class Course {
    //课程名字
    private String courseName;
    //课程ppt
    private String coursePPT;
    //课程视频
    private String courseVideo;
    //课程标题
    private String courseTitle;
    //课程的问题和答案
    private String courseQA;
    public String getCourseName() {
        return courseName;
    }
    public void setCourseName(String courseName) {
        this.courseName = courseName;
    }
    public String getCoursePPT() {
        return coursePPT;
    }
    public void setCoursePPT(String coursePPT) {
        this.coursePPT = coursePPT;
    }
    public String getCourseVideo() {
        return courseVideo;
    }
    public void setCourseVideo(String courseVideo) {
        this.courseVideo = courseVideo;
    }
    public String getCourseTitle() {
        return courseTitle;
    }
    public void setCourseTitle(String courseTitle) {
        this.courseTitle = courseTitle;
    }
    public String getCourseQA() {
        return courseQA;
    }
    public void setCourseQA(String courseQA) {
        this.courseQA = courseQA;
    }
    @Override
    public String toString() {
        return "Course{" +
                "courseName='" + courseName + '\'' +
                ", coursePPT='" + coursePPT + '\'' +
                ", courseVideo='" + courseVideo + '\'' +
                ", courseTitle='" + courseTitle + '\'' +
                ", courseQA='" + courseQA + '\'' +
                '}';
    }
    public Course(String courseName, String coursePPT, String courseVideo, String courseTitle, String courseQA) {
        this.courseName = courseName;
        this.coursePPT = coursePPT;
        this.courseVideo = courseVideo;
        this.courseTitle = courseTitle;
        this.courseQA = courseQA;
    }
    public Course() {}
}

2,抽象的builder类,一般具体的事物用使用抽象类,抽象的事物用接口,因此这里使用CourseBuilder 抽象类

package com.zhs.responsibility;
/**
 * @author zhenghuisheng
 * @date : 2022/9/16
 * 抽象类指的是具体存在的东西,接口之指的是一种抽象的东西,比如说会飞
 */
public abstract class CourseBuilder {
    public abstract void buildCourseName(String courseName);
    public abstract void buildCoursePPT(String coursePpt);
    public abstract void buildCourseVideo(String courseVideo);
    public abstract void buildCourseTitle(String courseTitle);
    public abstract void buildCourseQA(String courseQA);
    public abstract Course makeCourse();
}

3,具体的builder类,主要用于实现抽象类或者接口的抽象方法,因此这里创建一个CourseActualBuilder 类,用于继承上面的CourseBuilder 抽象类

package com.zhs.responsibility;
/**
 * @author zhenghuisheng
 * @date : 2022/9/16
 */
public class CourseActualBuilder extends CourseBuilder {
    //创建一个视频资源类
    private Course course = new Course();
    @Override
    public void buildCourseName(String courseName) {
        this.course.setCourseName(courseName);
    }
    @Override
    public void buildCoursePPT(String coursePpt) {
        this.course.setCoursePPT(coursePpt);
    }
    @Override
    public void buildCourseVideo(String courseVideo) {
        this.course.setCourseVideo(courseVideo);
    }
    @Override
    public void buildCourseTitle(String courseTitle) {
        this.course.setCourseTitle(courseTitle);
    }
    @Override
    public void buildCourseQA(String courseQA) {
        this.course.setCourseQA(courseQA);
    }
    @Override
    public Course makeCourse() {
        return this.course;
    }
}

4,指挥者,这里就是创建一个平台管理员充当这个指挥者,用于操作这个实现builder接口的对象,因此创建一个CourseManager 类

package com.zhs.responsibility;
/**
 * @author zhenghuisheng
 * @date : 2022/9/16
 * 管理员类,负责将资源整合并创建
 */
public class CourseManager {
    //资源构建器
    private CourseBuilder courseBuilder;
    //获取这个资源构建器
    public void setCourseBuilder(CourseBuilder courseBuilder ){
        this.courseBuilder = courseBuilder;
    }
    //返回这个构造器
    public Course getCourse(String courseName,String coursePPT,String courseVideo,String courseTitle,String courseQA){
        this.courseBuilder.buildCourseName(courseName);
        this.courseBuilder.buildCoursePPT(coursePPT);
        this.courseBuilder.buildCourseVideo(courseVideo);
        this.courseBuilder.buildCourseTitle(courseTitle);
        this.courseBuilder.buildCourseQA(courseQA);
        return courseBuilder.makeCourse();
    }
}

5,测试。这样的一个基本的建造者模式就创建好了

/**
 * @author zhenghuisheng
 * @date : 2022/9/16
 */
public class Test {
    public static void main(String[] args) {
        //获取构造类
        CourseBuilder courseBuilder = new CourseActualBuilder();
        //资源管理类
        CourseManager courseManager = new CourseManager();
        //管理员和这个构造器绑定
        courseManager.setCourseBuilder(courseBuilder);
        //获取资源
        Course course = courseManager.getCourse("1", "2", "3", "4", "5");
        System.out.println(course);
    }
}

4,代码改进

由于上面的建造者模式没有出现这个build的链式调用,并且需要一个这个指挥者CourseManager 类操作这个Builder类,因此对这两个方面进行一个优化。其代码如下,直接通过一个静态的内部类来实现这个属性的赋值,里面的每一个方法的返回值都是一个类对象,这样就可以使用这个链式调用的构造器了

package com.zhs.responsibility.improve;
/**
 * @author zhenghuisheng
 * @date : 2022/9/16
 * 直接通过一个静态的内部类来实现
 */
public class ImpoveSource {
    //课程名字
    private String courseName;
    //课程ppt
    private String coursePPT;
    //课程视频
    private String courseVideo;
    //课程标题
    private String courseTitle;
    //课程的问题和答案
    private String courseQA;
    @Override
    public String toString() {
        return "ImpoveSource{" +
                "courseName='" + courseName + '\'' +
                ", coursePPT='" + coursePPT + '\'' +
                ", courseVideo='" + courseVideo + '\'' +
                ", courseTitle='" + courseTitle + '\'' +
                ", courseQA='" + courseQA + '\'' +
                '}';
    }
    public ImpoveSource(ImproveCourseBuilder improveCourseBuilder){
        this.courseName = improveCourseBuilder.courseName;
        this.coursePPT = improveCourseBuilder.coursePPT;
        this.courseVideo = improveCourseBuilder.courseVideo;
        this.courseTitle = improveCourseBuilder.courseArticle;
        this.courseQA = improveCourseBuilder.courseQA;
    }
    //开始构造
    public static class ImproveCourseBuilder{
        private String courseName;
        private String coursePPT;
        private String courseVideo;
        private String courseArticle;
        private String courseQA;
        public ImproveCourseBuilder buildCourseName(String courseName){
            this.courseName = courseName;,
            return this;
        }
        public ImproveCourseBuilder buildCoursePPT(String coursePPT){
            this.coursePPT = coursePPT;
            return this;
        }
        public ImproveCourseBuilder buildCourseVideo(String courseVideo){
            this.courseVideo = courseVideo;
            return this;
        }
        public ImproveCourseBuilder buildCourseArticle(String courseArticle){
            this.courseArticle = courseArticle;
            return this;
        }
        public ImproveCourseBuilder buildCourseQA(String courseQA){
            this.courseQA = courseQA;
            return this;
        }
        //构建器
        public ImpoveSource build(){
            return new ImpoveSource(this);
        }
    }
}

测试类ImproveSourceTest

package com.zhs.responsibility.improve;
/**
 * @author zhenghuisheng
 * @date : 2022/9/16
 */
public class ImproveSourceTest {
    public static void main(String[] args) {
        //可以这个参数传错的问题,顺序的问题
        ImpoveSource build = new ImpoveSource.ImproveCourseBuilder()
                .buildCourseName("java")
                .buildCourseArticle("springboot入门到入土")
                .buildCoursePPT("springboot入门到入土PPT")
                .buildCourseVideo("springboot入门到入土视频")
                .buildCourseQA("springboot入门到入土问题答疑")
                .build();
        System.out.println(build);
    }
}

这样就实现了链式的调用,并对前面的代码进行了优化。同时这个Builder的过程,里面的顺序也可以随意,不需要像构造方法一样,里面必须按顺序传值


三,建造者模式在框架体现

1,Stringbuilder

Stringbuilder的append方法,返回类型的都是一个Stringbuilder的一个实现类,因此这个Stringbuilder的对象可以无限的被追加,StringBuffer和这个StringBuilder的原理一样,都是使用这个建造者模式。


1ed8550c8fe04923b752e6ce175a6f0c.png

2,CacheBuilder

在这个mybatis的缓存构造器里面,也是使用的这种build建造者模式,很明显的一个内容就是方法的返回值都是CacheBuilder,那么就可以简单的实现一个链式调用。


5fce3309b25344daabcf4c31a2e49a96.png

3,beanDefinitionBuilder

在spring容器中,所有的实例都会先生成一个BeanDefinition,那么就需要这个beanDefinitionBuilder的这个构造器。通过以下的方法全是返回这个beanDefinitionBuilder的类型可以发现,这个beanDefinitionBuilder也是使用了这个构造器模式


bc8b58cce397454fbb8544995ffc5226.png

4,SqlSessionFactoryBuilder和XMLConfigBuilder

在mybatis中,底层用了大量的建造者模式,如SqlSessionFactoryBuilder,XMLConfigBuilder,XMLMapperBuilder,XMLStatementBuilder,CacheBuilder,SqlSourceBuilder等这些都用了建造者模式

SqlSessionFactory build = new SqlSessionFactoryBuilder().build(reader);
XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);

8e7e4cd1054d486cad0e80ce1b1599eb.png

相关文章
|
3月前
|
设计模式 算法
设计模式--建造者模式 builder
这篇文章通过一个电脑购买的例子,详细解释了建造者模式的四个角色(产品类、抽象构建者、实体构建类和指导者类),并提供了相应的代码实现,阐述了建造者模式在设计复杂对象时的应用和优势。
设计模式--建造者模式 builder
|
2月前
|
设计模式 Java 程序员
[Java]23种设计模式
本文介绍了设计模式的概念及其七大原则,强调了设计模式在提高代码重用性、可读性、可扩展性和可靠性方面的作用。文章还简要概述了23种设计模式,并提供了进一步学习的资源链接。
47 0
[Java]23种设计模式
|
18天前
|
设计模式 JavaScript Java
Java设计模式:建造者模式详解
建造者模式是一种创建型设计模式,通过将复杂对象的构建过程与表示分离,使得相同的构建过程可以创建不同的表示。本文详细介绍了建造者模式的原理、背景、应用场景及实际Demo,帮助读者更好地理解和应用这一模式。
|
2月前
|
设计模式 监控 算法
Java设计模式梳理:行为型模式(策略,观察者等)
本文详细介绍了Java设计模式中的行为型模式,包括策略模式、观察者模式、责任链模式、模板方法模式和状态模式。通过具体示例代码,深入浅出地讲解了每种模式的应用场景与实现方式。例如,策略模式通过定义一系列算法让客户端在运行时选择所需算法;观察者模式则让多个观察者对象同时监听某一个主题对象,实现松耦合的消息传递机制。此外,还探讨了这些模式与实际开发中的联系,帮助读者更好地理解和应用设计模式,提升代码质量。
Java设计模式梳理:行为型模式(策略,观察者等)
|
3月前
|
存储 设计模式 安全
Java设计模式-备忘录模式(23)
Java设计模式-备忘录模式(23)
|
3月前
|
设计模式 存储 算法
Java设计模式-命令模式(16)
Java设计模式-命令模式(16)
|
3月前
|
设计模式 存储 缓存
Java设计模式 - 解释器模式(24)
Java设计模式 - 解释器模式(24)
|
3月前
|
设计模式 安全 Java
Java设计模式-迭代器模式(21)
Java设计模式-迭代器模式(21)
|
3月前
|
设计模式 缓存 监控
Java设计模式-责任链模式(17)
Java设计模式-责任链模式(17)
|
3月前
|
设计模式 运维 算法
Java设计模式-策略模式(15)
Java设计模式-策略模式(15)