推薦:Java設計模式彙總
建造者模式
定義
将一個複雜對象的建構與它的表示分離,使得同樣的建構過程可以建立不同的表示。
建立者模式隐藏了複雜對象的建立過程,它把複雜對象的建立過程加以抽象,通過子類繼承或者重載的方式,動态的建立具有複合屬性的對象。
類型
建立型。
例子
Course類(課程類),一個産品類。
package com.kaven.design.pattern.creational.builder;
public class Course {
private String courseName;
private String coursePPT;
private String courseVideo;
private String courseArticle;
//question and answer
private String courseQA;
public void setCourseName(String courseName) {
this.courseName = courseName;
}
public void setCoursePPT(String coursePPT) {
this.coursePPT = coursePPT;
}
public void setCourseVideo(String courseVideo) {
this.courseVideo = courseVideo;
}
public void setCourseArticle(String courseArticle) {
this.courseArticle = courseArticle;
}
public void setCourseQA(String courseQA) {
this.courseQA = courseQA;
}
@Override
public String toString() {
return "Course{" +
"courseName='" + courseName + '\'' +
", coursePPT='" + coursePPT + '\'' +
", courseVideo='" + courseVideo + '\'' +
", courseArticle='" + courseArticle + '\'' +
", courseQA='" + courseQA + '\'' +
'}';
}
}
CourseBuilder類(抽象類,也可以定義為接口),是課程(産品)的抽象建造者類,定義建立課程執行個體的各種接口。
package com.kaven.design.pattern.creational.builder;
public abstract class CourseBuilder {
public abstract void builderCourseName(String courseName);
public abstract void builderCoursePPT(String coursePPT);
public abstract void builderCourseVideo(String courseVideo);
public abstract void builderCourseArticle(String courseArticle);
public abstract void builderCourseQA(String courseQA);
public abstract Course makeCourse();
}
CourseActualBuilder類,是課程(産品)真正的建立者類。
package com.kaven.design.pattern.creational.builder;
public class CourseActualBuilder extends CourseBuilder {
private Course course = new Course();
public void builderCourseName(String courseName) {
course.setCourseName(courseName);
}
public void builderCoursePPT(String coursePPT) {
course.setCoursePPT(coursePPT);
}
public void builderCourseVideo(String courseVideo) {
course.setCourseVideo(courseVideo);
}
public void builderCourseArticle(String courseArticle) {
course.setCourseArticle(courseArticle);
}
public void builderCourseQA(String courseQA) {
course.setCourseQA(courseQA);
}
public Course makeCourse() {
return course;
}
}
Coach類,是一個指揮者類,應用層可以通過指揮者類進行産品執行個體的建立,而不是直接調用建造者類的相關方法。
package com.kaven.design.pattern.creational.builder;
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.builderCourseName(courseName);
this.courseBuilder.builderCoursePPT(coursePPT);
this.courseBuilder.builderCourseVideo(courseVideo);
this.courseBuilder.builderCourseArticle(courseArticle);
this.courseBuilder.builderCourseQA(courseQA);
return this.courseBuilder.makeCourse();
}
}
應用層代碼:
package com.kaven.design.pattern.creational.builder;
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);
}
}
結果:
Course{courseName='Java設計模式', coursePPT='Java設計模式PPT', courseVideo='Java設計模式視訊', courseArticle='Java設計模式手記', courseQA='Java設計模式問答'}
這便是一個建造者模式的例子,不過看起來還是挺複雜的。
改進
使用靜态内部類可以改進建造者模式。
Course類(課程類),與上面的Course類一樣,是一個産品類。
但在Course類中定義了一個靜态内部類CourseBuilder,并且這個靜态内部類CourseBuilder就是課程執行個體的實際建造者,可以好好體會下面的代碼。
package com.kaven.design.pattern.creational.builder.v2;
public class Course {
private String courseName;
private String coursePPT;
private String courseVideo;
private String courseArticle;
//question and answer
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;
}
@Override
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;
//question and 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);
}
}
}
應用層代碼:
由于上面的改進,建立課程執行個體的建造者模式更加簡潔,并且在應用層建立課程執行個體時更加友好(通過鍊式調用對課程執行個體屬性進行初始化,
關鍵在于靜态内部類CourseBuilder中的buildxxx()方法都是傳回this
)。
根據靜态内部類CourseBuilder中的代碼可以看出,每次調用buildxxx()方法其實都是初始化靜态内部類CourseBuilder執行個體的xxx屬性,最後通過調用build()方法,将this傳給Course類的構造方法建立課程執行個體(此時this的屬性都已經有值了,再通過this的這些屬性值來初始化課程執行個體的屬性)。
package com.kaven.design.pattern.creational.builder.v2;
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 );
}
}
與未改進的版本相比,通過鍊式調用對課程執行個體屬性進行初始化更加友好,還不容易出錯,像下面建立課程執行個體的代碼,屬性值很容易寫錯位置,改進版本的建造者模式在很多中間件以及架構中有使用。
Course course = coach.makeCourse("Java設計模式","Java設計模式PPT",
"Java設計模式視訊","Java設計模式手記","Java設計模式問答");
結果是一樣的。
Course{courseName='Java設計模式', coursePPT='Java設計模式PPT', courseVideo='Java設計模式視訊', courseArticle='Java設計模式手記', courseQA='Java設計模式問答'}
适用場景
- 需要生成的産品對象有複雜的内部結構,這些産品對象具備共性。
- 隔離複雜對象的建立和使用,并使得相同的建構過程可以建立不同的産品。
建造者模式與抽象工廠模式的比較
- 與抽象工廠模式相比,建造者模式傳回一個組裝好的完整産品,而抽象工廠模式傳回一系列相關的産品,這些産品位于不同的産品等級結構,構成了一個産品族。
- 在抽象工廠模式中,應用層執行個體化工廠類,然後調用工廠方法擷取所需産品對象,
,包括對象的組裝過程和建造步驟,它側重于一步步構造一個複雜對象,傳回一個完整的對象。而在建造者模式中,應用層可以不直接調用建造者類的相關方法,而是通過指揮者類來指導如何生成對象
- 如果将抽象工廠模式看成汽車配件生産工廠,生産一個産品族的産品,那麼建造者模式就是一個汽車組裝工廠,通過對部件的組裝可以傳回一輛完整的汽車
設計模式-抽象工廠模式(Abstract Factory Pattern)
優點
- 使用建造者模式可以使應用層不必知道産品内部組成的細節。
- 具體的建造者類之間是互相獨立的,這有利于系統的擴充。
- 具體的建造者互相獨立,是以可以對建造的過程逐漸細化,而不會對其他子產品産生任何影響。
- 建造者模式所建立的産品一般具有較多的共同點,其組成部分相似;如果産品之間的差異性很大,則不适合使用建造者模式,是以其使用範圍受到一定的限制。
- 如果産品的内部變化複雜,可能會導緻需要定義很多具體建造者類來實作這種變化,導緻系統變得很龐大。