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


    一,建造者模式

    1,基本概念

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

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

    2,建造者模式使用场景

    一个对象有非常复杂的内部结构,比如说很多属性等
    想把对象的创建和使用分离

    3,建造者优缺点

    3.1,优点

    封装性好,创建和使用分离
    扩展性好,建造类之间独立,在一定程度上解耦

    3.2,缺点

    会产生多余的Builder对象

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

    4,建造者模式四个角色

    Product :产品角色,一个具体的产品对象
    Builder:抽象的建造者,创建一个Product对象的各个部件的指定的接口和抽象类
    ConcreateBuilder:具体的构建者,实心接口,构建和装配各个部件
    Director:指挥者,构建一个使用Builder接口的对象,主要是创建一个复杂的对象。主要有两个作用,一个是隔离客户端与对象的生产的过程,而是负责控制产品对象的生产过程
    在这里插入图片描述

    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() {}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81

    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();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    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;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    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();
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    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);
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    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);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79

    测试类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);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

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

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

    1,Stringbuilder

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

    2,CacheBuilder

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

    3,beanDefinitionBuilder

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

    4,SqlSessionFactoryBuilder和XMLConfigBuilder

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

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

    在这里插入图片描述

  • 相关阅读:
    神经网络理论及应用答案,神经网络理论名词解释
    c# Parallel.For 循环内多线程并行操作
    #边学边考 必修5 高项:对人管理 第2章 项目沟通管理和干系人管理
    C++:指针
    TCP: 传输控制协议
    现代数据栈:高效开发数据,辅助企业决策
    微信小程序之自定义组件(OA项目个人主页及投票)
    分享金媒v10.3开源系统中CRM线下客户管理系统使用指南和小程序上架细分流程
    STL容器——vector
    C语言实现输入 n 个字符串,将它们按字母由小到大的顺序排列并输出
  • 原文地址:https://blog.csdn.net/zhenghuishengq/article/details/126911223