ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

设计模式-基础篇(创建型-建造者模式)

设计模式-基础篇(创建型-建造者模式) 这一篇带大家了解一下建造者模式。有兴趣可以翻一下前面的我写的其他设计模式如果堆设计模式不了解可以先看看设计模式的六大原则。设计模式-基础篇六大原则设计模式-基础篇创建型:单例模式设计模式-基础篇(创建型:工厂)建造者模式是一种创建型模式主要用来将一个复杂对象的创建过程拆分成一个个小步骤。一步步构建出来。为什么使用建造者模式对象构建过程复杂如果创建的对象有很多的步骤或者参数。直接在构造函数或者方法参数中传递就会显得非常复杂。而建造者模式就能将这些复杂的过程拆分开。使得对象的创建过程变得清晰。需要灵活的构建方式根据需求的不同构建相似的对象建造者允许我们更改某些步骤创建出不同的对象。构建过程与表示进行分离一个构建过程创建出不同表示的对象。什么场景下下可以使用建造者模式复杂表单或者请求对象的构建订单提交时可以使用建造者避免参数过长或者参数顺序错乱。导出文件内容构建导出pdf页眉表格图片段落这些可以使用。建造者的基本结构产品类 要构建的复杂对象抽象建造者类构建产品的方法以及返回产品的方法具体建造者类负责各部分的构建细节实现builder。指挥者屏蔽构建过程的细节指挥建造者去构建产品。客户端发起建造请求选择具体的建造者并交给指挥者进行构建。建造者模式的优点结构清晰过程可控。便于构建不同版本的对象不同的建造者可以构建结构类似配置不同的对象。代码容易扩展后续新增构建步骤也以继续增加。建造者模式的缺点增加类的数量额外引入了建造者类和指挥者类。不适合构建差异太大的对象适用于有共同构建步骤的对象对过对象的构建逻辑不一样就会显得臃肿。Jdk的StringBuilder() 方法就是一个建造者模式stf时指挥者append方法是具体建造者而tostring则是结果的返回。代码演示创建一个导出pdf的产品类。importjava.util.ArrayList;importjava.util.List;/** * 产品角色PDF文档实体存放标题、段落、图片 */publicclassPdfDocument{//标题privateStringtitle;//段落文本集合privateListStringparagraphListnewArrayList();//图片路径集合模拟图片privateListStringimageListnewArrayList();publicvoidsetTitle(Stringtitle){this.titletitle;}publicvoidaddParagraph(Stringcontent){paragraphList.add(content);}publicvoidaddImage(StringimagePath){imageList.add(imagePath);}//模拟输出PDF文档内容实际项目这里调用PDF工具生成文件publicvoidshowDocumentInfo(){System.out.println(生成PDF文档);System.out.println(文档标题title);System.out.println(段落内容);paragraphList.forEach(p-System.out.println(\tp));System.out.println(插入图片路径);imageList.forEach(img-System.out.println(\timg));System.out.println(\n);}}定义抽象建造者和具体建造者。/** * 抽象建造者定义构建PDF各个组件的统一方法 */publicabstractclassPdfBuilder{protectedPdfDocumentpdfDocument;//初始化产品publicvoidcreateNewPdf(){pdfDocumentnewPdfDocument();}//构建标题publicabstractvoidbuildTitle(Stringtitle);//构建段落publicabstractvoidbuildParagraph(Stringparagraph);//构建图片publicabstractvoidbuildImage(StringimagePath);//获取最终成品publicabstractPdfDocumentgetResult();}/** * 具体建造者实现抽象建造者组装PDF各个部件 */publicclassCustomPdfBuilderextendsPdfBuilder{OverridepublicvoidbuildTitle(Stringtitle){pdfDocument.setTitle(title);}OverridepublicvoidbuildParagraph(Stringparagraph){pdfDocument.addParagraph(paragraph);}OverridepublicvoidbuildImage(StringimagePath){pdfDocument.addImage(imagePath);}OverridepublicPdfDocumentgetResult(){returnpdfDocument;}}由指挥者进行调度。/** * 指挥者编排PDF文档构建步骤控制组装顺序 */publicclassPdfDirector{/** * 指挥构建完整PDF文档 * param builder 建造者 * param title 标题 * param paragraphs 多个段落 * param images 多张图片路径 * return 组装完成PDF文档 */publicPdfDocumentconstruct(PdfBuilderbuilder,Stringtitle,ListStringparagraphs,ListStringimages){//1.创建空白PDFbuilder.createNewPdf();//2.设置标题builder.buildTitle(title);//3.循环添加段落for(Stringpara:paragraphs){builder.buildParagraph(para);}//4.循环添加图片for(Stringimg:images){builder.buildImage(img);}//5.返回成品PDFreturnbuilder.getResult();}}测试用例importjava.util.List;publicclassClientDemo{publicstaticvoidmain(String[]args){//1.创建具体建造者PdfBuilderpdfBuildernewCustomPdfBuilder();//2.创建指挥者PdfDirectordirectornewPdfDirector();//模拟业务数据Stringtitle2026年度数据报告;ListStringparagraphsList.of(第一部分全年业务总体概况,第二部分各部门指标完成情况,第三部分下一年工作计划);ListStringimagesList.of(/data/img/chart1.png,/data/img/chart2.png);//指挥者指挥建造客户端只传入数据不关心内部组装步骤PdfDocumentpdfDocumentdirector.construct(pdfBuilder,title,paragraphs,images);//输出最终PDFpdfDocument.showDocumentInfo();}}很多场景可以省略掉指挥者直接将指挥者逻辑写在客户端如下省略到指挥者我们日常开发也是这样。importjava.util.List;publicclassClientDemo{publicstaticvoidmain(String[]args){//1.创建具体建造者PdfBuilderbuildernewCustomPdfBuilder();//模拟业务数据Stringtitle2026年度数据报告;ListStringparagraphsList.of(第一部分全年业务总体概况,第二部分各部门指标完成情况,第三部分下一年工作计划);ListStringimagesList.of(/data/img/chart1.png,/data/img/chart2.png);//1.创建空白PDFbuilder.createNewPdf();//2.设置标题builder.buildTitle(title);//3.循环添加段落for(Stringpara:paragraphs){builder.buildParagraph(para);}//4.循环添加图片for(Stringimg:images){builder.buildImage(img);}//5.返回成品PDFbuilder.getResult();//输出最终PDFpdfDocument.showDocumentInfo();}}这样可以达到相同效果算是建造者模式的变种省略了一个类。
返回列表