1 定义域特征
定义:将一个复杂的对象构建与其表示分离,使得同样的构建过程可以创建不同的表示。特征:用户只需要指定需要建造的类型即可,对于中间的细节不考虑。
2 代码实现及分析
场景:假设一个课程有许多部分组成:PPT、视频、手记、问答,需要在应用层根据不同要求创建不同的课程并设置相应的组成部分。
course类:
//课程类 public class Course { private String courseName; private String coursePPT; private String courseVideo; //笔记 private String courseArticle; //question & answer 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 getCourseArticle() { return courseArticle; } public void setCourseArticle(String courseArticle) { this.courseArticle = courseArticle; } 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 + '\'' + ", courseArticle='" + courseArticle + '\'' + ", courseQA='" + courseQA + '\'' + '}'; } }
CourserBuilder:抽象的课程建造者
/** * 课程建造者 */ 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 buildCourseArticle(String courseArticle); public abstract void buildCourseQA(String courseQA); //制作一个课程 public abstract Course makeCourse(); }
CourserActualBuilder:
/** * 课程的真实构建类 */ public class CourseActualBuilder extends CourseBuilder { private Course course = new Course(); @Override public void buildCourseName(String courseName) { course.setCourseName(courseName); } @Override public void buildCoursePPT(String coursePPT) { course.setCoursePPT(coursePPT); } @Override public void buildCourseVideo(String courseVideo) { course.setCourseVideo(courseVideo); } @Override public void buildCourseArticle(String courseArticle) { course.setCourseArticle(courseArticle); } @Override public void buildCourseQA(String courseQA) { course.setCourseQA(courseQA); } @Override public Course makeCourse() { return course; } }
Coach:辅助类
/** * 课程教练,通过接收到的课程信息来构建课程。 */ public class Coach { private CourseBuilder courseBuilder; //set方式注入 public void setCourseBuilder(CourseBuilder courseBuilder) { this.courseBuilder = courseBuilder; } //根据接收到的课程的信息制作课程。 public Course makeCourse(String courseName,String coursePPT, String courseVideo,String courseArticle, String courseQA){ this.courseBuilder.buildCourseName(courseName); this.courseBuilder.buildCoursePPT(coursePPT); this.courseBuilder.buildCourseVideo(courseVideo); this.courseBuilder.buildCourseArticle(courseArticle); this.courseBuilder.buildCourseQA(courseQA); return this.courseBuilder.makeCourse(); } }
Test类:应用层
/** * 测试类 */ public class Test { public static void main(String[] args) { //多态父类引用子类实现 CourseBuilder courseBuilder = new CourseActualBuilder(); Coach coach = new Coach(); //在coach中注入courseBuilder coach.setCourseBuilder(courseBuilder); Course course = coach.makeCourse("Java设计模式精讲", "Java设计模式精讲PPT", "Java设计模式精讲视频",
"Java设计模式精讲手记","Java设计模式精讲问答");
System.out.println(course); } }
在应用层中通过向coach传递参数来构建一个具体的对象,coach和CourserBuilder为组合的关系,1对1。CourserActualBuilder与Course同样为组合的1对1关系,其类图关系如下图所示。

3 优化
对于上面的代码,coach不是必须的可以让应用层直接控制,采用静态内部类进行改善。
Course类:
public class Course { private String courseName; private String coursePPT; private String courseVideo; private String courseArticle; //question & answer private String courseQA; //这里的CourseBuilder就是静态内部类返回的对象 public Course(CourseBuilder courseBuilder) { this.courseName = courseBuilder.courseName; this.coursePPT = courseBuilder.coursePPT; this.courseVideo = courseBuilder.courseVideo; this.courseArticle = courseBuilder.courseArticle; this.courseQA = courseBuilder.courseQA; } //采用静态内部类创建Course对象 public static class CourseBuilder{ private String courseName; private String coursePPT; private String courseVideo; private String courseArticle; //question & answer private String courseQA; //返回对象本身可以让应用层链式调用 public CourseBuilder buildCourseName(String courseName){ this.courseName = courseName; return this; } public CourseBuilder buildCoursePPT(String coursePPT) { this.coursePPT = coursePPT; return this; } public CourseBuilder buildCourseVideo(String courseVideo) { this.courseVideo = courseVideo; return this; } public CourseBuilder buildCourseArticle(String courseArticle) { this.courseArticle = courseArticle; return this; } public CourseBuilder buildCourseQA(String courseQA) { this.courseQA = courseQA; return this; } public Course build(){ return new Course(this); } } @Override public String toString() { return "Course{" + "courseName='" + courseName + '\'' + ", coursePPT='" + coursePPT + '\'' + ", courseVideo='" + courseVideo + '\'' + ", courseArticle='" + courseArticle + '\'' + ", courseQA='" + courseQA + '\'' + '}'; } }
Test类:
public class Test { public static void main(String[] args) { //链式调用 Course course = new Course.CourseBuilder().buildCourseName("Java设计模式精讲").buildCoursePPT("Java设计模式精讲PPT").buildCourseVideo("Java设计模式精讲视频").build(); System.out.println(course); } }
这样其类比上部分要简化很多,其关系图如下:

4 源码分析
(1)JDK源码
StringBuilder类中的append方法:
public StringBuilder append(StringBuffer sb) { super.append(sb); return this; } @Override public StringBuilder append(CharSequence s) { super.append(s); return this; }
可以看出与优化部分的代码类似StringBuilder在建造时没有采用过多的抽象而是采用链式方法直接进行修改。同样的还有StringBuffer,加了关键字synchronized保证了其线程安全
@Override public synchronized StringBuffer append(Object obj) { toStringCache = null; super.append(String.valueOf(obj)); return this; } @Override public synchronized StringBuffer append(String str) { toStringCache = null; super.append(str); return this; }
(2)mybatis源码
在SqlSessionFactoryBuilder类中的build方法:根据传入的confi构建默认的SqlSession
public SqlSessionFactory build(Configuration config) { return new DefaultSqlSessionFactory(config); }
寻找Configuration具体怎么来的,首先在SqlSessionFactoryBuilder类中有如下代码:
//在XMLConfigBuilder完成复杂创建的基础上,做一层简单的封装,这里用建造者来包装一层建造者 public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) { SqlSessionFactory var5; try { //在建造者模式中使用建造者,XMLConfigBuilder负责完成复杂流程的创建 XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties); var5 = this.build(parser.parse()); } catch (Exception var14) { throw ExceptionFactory.wrapException("Error building SqlSession.", var14); } finally { ErrorContext.instance().reset(); try { inputStream.close(); } catch (IOException var13) { ; } } return var5; }
在上述代码中深入:var5 = this.build(parser.parse());深入parse()方法在XMLConfigBuilder类中有:此时得到了Configuration
public Configuration parse() { if (this.parsed) { throw new BuilderException("Each XMLConfigBuilder can only be used once."); } else { this.parsed = true; //调用方法 this.parseConfiguration(this.parser.evalNode("/configuration")); return this.configuration; } }
继续深入:this.parseConfiguration方法便可达到复杂配置对象配置流程,至此建造者模式套用建造者模式的流程全部结束。
//XNode根节点,完成复杂流程的封装工作 private void parseConfiguration(XNode root) { try { Properties settings = this.settingsAsPropertiess(root.evalNode("settings")); this.propertiesElement(root.evalNode("properties")); this.loadCustomVfs(settings); this.typeAliasesElement(root.evalNode("typeAliases")); this.pluginElement(root.evalNode("plugins")); this.objectFactoryElement(root.evalNode("objectFactory")); this.objectWrapperFactoryElement(root.evalNode("objectWrapperFactory")); this.reflectorFactoryElement(root.evalNode("reflectorFactory")); this.settingsElement(settings); this.environmentsElement(root.evalNode("environments")); this.databaseIdProviderElement(root.evalNode("databaseIdProvider")); this.typeHandlerElement(root.evalNode("typeHandlers")); this.mapperElement(root.evalNode("mappers")); } catch (Exception var3) { throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + var3, var3); } }
0