该项目源码地址:https://github.com/lastwhispers/code/tree/master/java-basic/design-pattern
(设计模式相关代码与笔记)
1. 定义
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示
2. 适用场景
- 如果一个对象有非常复杂的内部结构,在用户不知道对象的建造过程和细节的情况下就可以直接创建复杂的对象。
- 想把复杂对象的创建和使用分离。
3. 类图与角色
- Director:指挥者/导演类,负责安排已有模块的顺序,然后告诉Builder开始建造。
- Builder:抽象建造者,规范产品的组建,一般由子类实现。
- ConcreteBuilder:具体建造者,实现抽象类定义的所有方法,并且返回一个组建好的对象。
- Product:产品类,通常实现了模板方法模式。
4. 代码实例
背景:建造慕课网的java、python课程。
过程:课程指导员(Coach)将课程(Course)划分为几个部分(CourseBuilder)(课程名,课程PPT,课程视频,课程手记,课程问答),让真正建造的人(CourseActualBuilder)制作课程。
4.1 V1版本
(1)定义需要建造的课程(Course)
类图中对应的角色 Product
public class Course {
private String courseName;
private String coursePPT;
private String courseVideo;
private String courseArticle;
private String courseQA;
@Override
public String toString() {
return "Course{" +
"courseName='" + courseName + '\'' +
", coursePPT='" + coursePPT + '\'' +
", courseVideo='" + courseVideo + '\'' +
", courseArticle='" + courseArticle + '\'' +
", courseQA='" + 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;
}
}
(2)定义制作的过程(Builder)
类图中对应的角色 Builder
public abstract class CourseBuilder {
// private String courseName;
// private String coursePPT;
// private String courseVideo;
// private String courseArticle;
// private String courseQA;
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();
}
(3)定义真正建造的人(CourseActualBuilder)
类图中对应的角色 ConcreteBuilder
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;
}
}
(4)定义指挥者(Coach)
类图中对应的角色 Director
public class Coach {
private CourseBuilder courseBuilder;
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();
}
}
查看此时的类图,标准的建造者模式
(5)测试
public class Test {
public static void main(String[] args) {
CourseBuilder courseBuilder = new CourseActualBuilder();
Coach coach = new Coach();
coach.setCourseBuilder(courseBuilder);
Course course = coach.makeCourse("Java设计模式",
"Java设计模式PPT",
"Java设计模式视频",
"Java设计模式手记",
"Java设计模式问答");
System.out.println(course);
}
}
测试结果
此时的类图,应用层选择不同builder交个Coach(指导者),Coach建造不同的课程。
4.2 V2版本
使用链式调用
public class Course {
private String courseName;
private String coursePPT;
private String courseVideo;
private String courseArticle;
private String courseQA;
public Course(CourseBuilder courseBuilder) {
this.courseName = courseBuilder.courseName;
this.coursePPT = courseBuilder.coursePPT;
this.courseVideo = courseBuilder.courseVideo;
this.courseArticle = courseBuilder.courseArticle;
this.courseQA = courseBuilder.courseQA;
}
public String toString() {
return "Course{" +
"courseName='" + courseName + '\'' +
", coursePPT='" + coursePPT + '\'' +
", courseVideo='" + courseVideo + '\'' +
", courseArticle='" + courseArticle + '\'' +
", courseQA='" + courseQA + '\'' +
'}';
}
public static class CourseBuilder{
private String courseName;
private String coursePPT;
private String courseVideo;
private String courseArticle;
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);
}
}
}
测试代码
public class Test {
public static void main(String[] args){
Course course = new Course.CourseBuilder()
.buildCourseName("Java设计模式")
.buildCoursePPT("Java设计模式PPT")
//.buildCourseVideo("Java设计模式视频")
//.buildCourseArticle("Java设计模式手记")
.buildCourseQA("Java设计模式问答").build();
System.out.println(course);
}
}
测试结果
此时类图
5. 优点
- 封装性好,创建和使用分离
- 扩展性好、建造类之间独立、一定程度上解耦
6. 缺点
- 产生多余的builder对象
- 产品内部发送变化,建造者都要修改,成本比较大
7. 建造者与工厂模式区别
建造者模式
- 注重于方法的调用顺序
- 可以创建复杂的对象
- 不仅要知道创建了那些产品,还需要知道创建的产品由哪些部分组成的
工厂模式
- 注重于创建产品
- 创建的产品都是一个模样
- 创建产品出来后就没事了(相对于建造者模式)
8. 扩展-JDK1.7源码中的建造者模式
8.1 StringBuilder
StringBuilder中一部分源码,典型的建造者模式
public StringBuilder append(boolean b) {
super.append(b);
return this;
}
public StringBuilder append(char c) {
super.append(c);
return this;
}
public StringBuilder append(int i) {
super.append(i);
return this;
}
public StringBuilder append(long lng) {
super.append(lng);
return this;
}
public StringBuilder append(float f) {
super.append(f);
return this;
}
public StringBuilder append(double d) {
super.append(d);
return this;
}
8.2 StringBuffer
StringBuffer中一部分源码,比StringBuilder多一个synchronized,典型的建造者模式
public synchronized StringBuffer append(boolean b) {
super.append(b);
return this;
}
public synchronized StringBuffer append(char c) {
super.append(c);
return this;
}
public synchronized StringBuffer append(int i) {
super.append(i);
return this;
}
8.3 ImmutableSet
类似于V2版本,可以看到builder方法返回this,在builder构造器里面创建对象
8.4 BeanDefinitionBuilder
8.5 SqlSessionFactoryBuilder
在建造者模式里面再用了建造者模式