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() {}
}
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的原理一样,都是使用这个建造者模式。
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);
相关文章
- Servlet使用适配器模式进行增删改查案例(BaseDao.java)
- java设计模式6--适配器模式(Adapter )
- (Java实现) 蓝桥杯 国赛 重复模式
- Java 蓝桥杯 算法训练 字符串的展开 (JAVA语言实现)
- 【JAVA】毕向东Java基础视频教程-笔记
- 【JAVA】MacBook安装Java环境及eclipse
- Java经典设计模式之五大创建型模式(附实例和详解)
- Simple Logging Facade for Java (SLF4J)作用(java日志框架)
- Java中String类的concat方法___java的String字符串的concat()方法连接字符串和“+“连接字符串解释
- Java设计模式菜鸟系列(十五)建造者模式建模与实现
- 详解jvm之java类加载机制和类加载器(ClassLoader) 深入理解Java类加载器(ClassLoader) 如何自定义类加载器 深入说明双亲委派 双亲委派模型的破坏者-线程上下文类加载器
- Java——设计模式(装饰模式_IO)
- 浅析JAVA设计模式之工厂模式(一)
- java-信息安全(二)-对称加密算法工作模式ECB,CBC,CRT、DES,3DES,AES,Blowfish,RC2,RC4
- Java设计模式------------策略模式
- Java经典23种设计模式之结构型模式(一)
- java设计模式:观察者模式
- Java设计模式之——装饰者模式(Decorator pattern)
- java设计模式——多例模式
- Java观察者模式:轻松实现对象间的一对多依赖
- 【java】Java 内存模型
- Java 设计模式——组合模式
- JAVA开发讲义(二)-Java程序设计之数据之谜一