摘要:建造者實(shí)現(xiàn)抽象類的所有未實(shí)現(xiàn)的方法,具體來說一般是兩項(xiàng)任務(wù)組建產(chǎn)品返回組建好的產(chǎn)品。
0x01.定義與類型
定義:將一個(gè)復(fù)雜對象的構(gòu)建與它的表示分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示。
用戶只需指定需要建造的類型就可以得到他們,建造過程及細(xì)節(jié)不需要知道
類型:創(chuàng)建型
實(shí)現(xiàn)建造模式的兩種方式
1.抽象建造者UML:
Java實(shí)現(xiàn)
/** * 教練類,封裝了具體構(gòu)建的細(xì)節(jié) */ public class Coach { private AProductBuilder productBuilder; public void setProductBuilder(AProductBuilder productBuilder) { this.productBuilder = productBuilder; } public Product createProduct(String property) { productBuilder.buildProperty(property); return this.productBuilder.makeProduct(); } } /** * 抽象的構(gòu)建,每添加新的構(gòu)建方式,只需要繼承這個(gè)抽象類即可 */ public abstract class AProductBuilder { /** * 構(gòu)建具體屬性,只是mock一個(gè),可以有很多個(gè) * @param property */ abstract void buildProperty(String property); /** * 返回被構(gòu)建的對象 * @return */ abstract Product makeProduct(); } /** * 產(chǎn)品具體的構(gòu)建類 */ public class ProductActualBuilder extends AProductBuilder { private Product product = new Product(); @Override void buildProperty(String property) { product.setProperty(property); } @Override Product makeProduct() { return product; } } /** * 產(chǎn)品類 */ public class Product { /** * 產(chǎn)品實(shí)現(xiàn)細(xì)節(jié),可以很多個(gè)屬性,這里只mock了一個(gè) */ private String property; public void setProperty(String property) { this.property = property; } public String getProperty() { return property; } }
測試應(yīng)用類
public class Test { public static void main(String[] args) { Coach coach = new Coach(); coach.setProductBuilder(new ProductActualBuilder()); Product product = coach.createProduct("測試屬性"); System.out.println(product.getProperty()); } }
輸出結(jié)果
測試屬性
抽象建造者模式中的元素
產(chǎn)品類:一般是一個(gè)較為復(fù)雜的對象,也就是說創(chuàng)建對象的過程比較復(fù)雜,一般會有比較多的代碼量。在本類圖中,產(chǎn)品類是一個(gè)具體的類,而非抽象類。實(shí)際編程中,產(chǎn)品類可以是由一個(gè)抽象類與它的不同實(shí)現(xiàn)組成,也可以是由多個(gè)抽象類與他們的實(shí)現(xiàn)組成。
抽象建造者:引入抽象建造者的目的,是為了將建造的具體過程交與它的子類來實(shí)現(xiàn)。這樣更容易擴(kuò)展。一般至少會有兩個(gè)抽象方法,一個(gè)用來建造產(chǎn)品,一個(gè)是用來返回產(chǎn)品。
建造者:實(shí)現(xiàn)抽象類的所有未實(shí)現(xiàn)的方法,具體來說一般是兩項(xiàng)任務(wù):組建產(chǎn)品;返回組建好的產(chǎn)品。
教練類:負(fù)責(zé)調(diào)用適當(dāng)?shù)慕ㄔ煺邅斫M建產(chǎn)品,教練類一般不與產(chǎn)品類發(fā)生依賴關(guān)系,與教練類直接交互的是建造者類。一般來說,教練類被用來封裝程序中易變的部分。
2.使用靜態(tài)內(nèi)部類和鏈?zhǔn)秸{(diào)用UML:
Java實(shí)現(xiàn)
/** * 產(chǎn)品類 */ public class Product { /** * 產(chǎn)品屬性,只是舉了一個(gè)例子,可以有很多個(gè) */ private String property; /** * 產(chǎn)品的構(gòu)建 構(gòu)造方法 * @param productBuilder */ public Product (ProductBuilder productBuilder) { this.property = productBuilder.property; } public String getProperty() { return property; } public void setProperty(String property) { this.property = property; } /** * 產(chǎn)品構(gòu)建類 */ public static class ProductBuilder { private String property; public ProductBuilder builderProperty (String property) { this.property = property; return this; } public Product build() { return new Product(this); } } }
輸出結(jié)果
測試屬性
靜態(tài)內(nèi)部類建造者模式的元素
產(chǎn)品:最終我們需要的結(jié)果,較為復(fù)雜或創(chuàng)建過程較為復(fù)雜的對象。
產(chǎn)品的構(gòu)建類:builder類是整個(gè)建造者模式的核心,具體由兩項(xiàng)任務(wù),一是構(gòu)建產(chǎn)品細(xì)節(jié),二是返回構(gòu)建好的產(chǎn)品。
0x02.適用場景如果一個(gè)對象有非常復(fù)雜的內(nèi)部結(jié)構(gòu)(很多屬性),這個(gè)時(shí)候可以考慮適用建造者模式。
想把復(fù)雜對象的創(chuàng)建和使用分離的時(shí)候。
0x03.優(yōu)點(diǎn)封裝性好,創(chuàng)建和使用分離,使用建造者模式可以有效的封裝變化,在使用建造者模式的場景中,一般產(chǎn)品類和建造者類是比較穩(wěn)定的。
擴(kuò)展性好,建造類之間獨(dú)立,一定程度上解耦,如果有新的需求,通過實(shí)現(xiàn)一個(gè)新的建造者類就可以完成,基本上不用修改之前已經(jīng)測試通過的代碼,因此也就不會對原有功能引入風(fēng)險(xiǎn)。
0x04.缺點(diǎn)會產(chǎn)生多余的Builder對象。
產(chǎn)品內(nèi)部發(fā)生變化,建造者都要修改,成本較大。
0x05.具體Java實(shí)現(xiàn)場景介紹:課程有課程名字,視頻,PPT和手記,舉例構(gòu)建這個(gè)對象
1.抽象建造類的實(shí)現(xiàn)具體的實(shí)現(xiàn)
/** * 課程教練類 */ 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.buildCourseArticle(courseArticle); this.courseBuilder.buildCourseVideo(courseVideo); this.courseBuilder.buildCourseQA(courseQA); return this.courseBuilder.makeCourse(); } } /** * 建造者的具體實(shí)現(xiàn)與應(yīng)用 */ 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(); } /** * 建造者的具體實(shí)現(xiàn) */ 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; } } /** * 具體產(chǎn)品的實(shí)例:課程 */ 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 + """ + "}"; } }
測試與應(yīng)用
/** * 測試與應(yīng)用 */ 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設(shè)計(jì)模式精講", "Java設(shè)計(jì)模式精講PPT", "Java設(shè)計(jì)模式精講視頻", "Java設(shè)計(jì)模式精講手記", "Java設(shè)計(jì)模式精講問答" ); System.out.println(course); } }
輸出結(jié)果
Course{courseName="Java設(shè)計(jì)模式精講", coursePPT="Java設(shè)計(jì)模式精講PPT", courseVideo="Java設(shè)計(jì)模式精講視頻", courseArticle="Java設(shè)計(jì)模式精講手記", courseQA="Java設(shè)計(jì)模式精講問答"}
UML類圖
2.靜態(tài)內(nèi)部類建造者模式具體的實(shí)現(xiàn)
/** * 課程類 */ public class Course { private String courseName; private String coursePPT; private String courseVideo; private String courseArticle; //question & answer private String courseQA; public Course(CourseBuilder courseBuilder) { this.courseName = courseBuilder.courseName; this.courseArticle = courseBuilder.courseArticle; this.coursePPT = courseBuilder.coursePPT; this.courseVideo = courseBuilder.courseVideo; this.courseQA = courseBuilder.courseQA; } @Override public String toString() { return "Course{" + "courseName="" + courseName + """ + ", coursePPT="" + coursePPT + """ + ", courseVideo="" + courseVideo + """ + ", courseArticle="" + courseArticle + """ + ", courseQA="" + courseQA + """ + "}"; } /** * 課程靜態(tài)builder類 */ 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); } } }
測試與應(yīng)用
/** * 測試與應(yīng)用 */ public class Test { public static void main(String[] args) { Course course1 = new Course.CourseBuilder() .buildCourseName("Java課程精講") .buildCourseArticle("Java課程精講手機(jī)") .buildCoursePPT("Java課程精講PPT") .buildCourseVideo("Java課程精講視頻") .build(); System.out.println(course1.toString()); Course course2 = new Course.CourseBuilder() .buildCourseName("Java課程精講") .buildCourseVideo("Java課程精講視頻") .build(); System.out.println(course2.toString()); } }
輸出結(jié)果
Course{courseName="Java課程精講", coursePPT="Java課程精講PPT", courseVideo="Java課程精講視頻", courseArticle="Java課程精講手機(jī)", courseQA="null"} Course{courseName="Java課程精講", coursePPT="null", courseVideo="Java課程精講視頻", courseArticle="null", courseQA="null"}
UML
0x06.建造者和工廠對比建造者和工廠模式都屬于創(chuàng)建類的設(shè)計(jì)模式,本身的場景很相似。
建造者:注重方法的調(diào)用順序,建造復(fù)雜的產(chǎn)品,由很多復(fù)雜的部件組成,不止創(chuàng)建產(chǎn)品還要知道產(chǎn)品的組成。
工廠:注重產(chǎn)品,產(chǎn)品基本都是一個(gè)樣子,只是生產(chǎn)產(chǎn)品,不關(guān)心產(chǎn)品組成。
0x07.源碼中的建造者模式StringBuilder
StringBuffer
Guava: ImtableSet
CacheBuilder
Spring: BeanDefinitionBuilder
MyBatis: SqlSessionFactoryBuilder
0x08.樣例代碼建造者模式:https://github.com/sigmako/design-pattern/tree/master/builder
0x09.參考慕課網(wǎng)設(shè)計(jì)模式精講: https://coding.imooc.com/class/270.html
23種設(shè)計(jì)模式(4):建造者模式: https://blog.csdn.net/zhengzhb/article/details/7375966
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/74860.html
摘要:參考文章設(shè)計(jì)模式之建造者模式一什么是建造者模式建造者模式是將一個(gè)復(fù)雜的對象的構(gòu)建與它的表示分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示。 參考文章:java設(shè)計(jì)模式之建造者模式 一、什么是建造者模式建造者模式:是將一個(gè)復(fù)雜的對象的構(gòu)建與它的表示分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示。工廠類模式提供的是創(chuàng)建單個(gè)類的模式,而建造者模式則是將各種產(chǎn)品集中起來進(jìn)行管理,用來創(chuàng)建復(fù)合對象,所謂...
摘要:建造者模式實(shí)現(xiàn)建造者模式實(shí)現(xiàn)創(chuàng)建抽象建造者類創(chuàng)建具體建造者類。建造者模式使用場景建造者模式使用場景相同的方法,不同的執(zhí)行順序,產(chǎn)生不同的事件結(jié)果時(shí),可以采用建造者模式。1、什么是建造者模式 Separate the construction of a complex object from its representation so that the same constructi...
1、什么是建造者模式Separate the construction of a complex object from its representation so that the same construction process can create different representations.將一個(gè)復(fù)雜對象的構(gòu)建與它的表示分離, 使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示。 說人話:將構(gòu)...
摘要:本質(zhì)建造者設(shè)計(jì)模式分離了對象子組件的構(gòu)造過程和組裝過程,實(shí)現(xiàn)了構(gòu)建與組裝的解耦,不同的構(gòu)建器相同的組裝順序以及相同的構(gòu)建器不同的組裝順序都可以創(chuàng)建出不同的對象,使得構(gòu)建與組裝充分解耦,進(jìn)而實(shí)現(xiàn)構(gòu)建算法與組裝算法的解耦,從而實(shí)現(xiàn)更好的復(fù)用。 這是設(shè)計(jì)模式系列的第二篇——建造者設(shè)計(jì)模式,我希望推送的文章是一個(gè)系列的,盡量保持一樣的寫作風(fēng)格,盡量把我理解的闡述清楚,關(guān)于建造者設(shè)計(jì)模式主要從以...
閱讀 3591·2021-11-24 10:19
閱讀 3730·2021-09-30 09:47
閱讀 1293·2019-08-30 15:56
閱讀 790·2019-08-29 15:11
閱讀 905·2019-08-29 13:43
閱讀 3570·2019-08-28 18:25
閱讀 2160·2019-08-26 13:27
閱讀 1439·2019-08-26 11:44