日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > asp.net >内容正文

asp.net

《研磨设计模式》chap8 生成器模式Builder

發(fā)布時(shí)間:2025/3/21 asp.net 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 《研磨设计模式》chap8 生成器模式Builder 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

場(chǎng)景:現(xiàn)有一“導(dǎo)出數(shù)據(jù)”的需求,分別導(dǎo)出到文本和xml。

1. 正常編碼

/*** 導(dǎo)出數(shù)據(jù)到文本文件的對(duì)象*/ public class ExportToTxt {/*** 導(dǎo)出數(shù)據(jù)到文本文件* @param ehm 文件頭的內(nèi)容* @param mapData 數(shù)據(jù)的內(nèi)容* @param efm 文件尾的內(nèi)容*/public void export(ExportHeaderModel ehm,Map<String,Collection<ExportDataModel>> mapData,ExportFooterModel efm){//用來記錄最終輸出的文件內(nèi)容StringBuffer buffer = new StringBuffer();//1:先來拼接文件頭的內(nèi)容buffer.append(ehm.getDepId()+","+ehm.getExportDate()+"\n");//2:接著來拼接文件體的內(nèi)容for(String tblName : mapData.keySet()){//先拼接表名稱buffer.append(tblName+"\n");//然后循環(huán)拼接具體數(shù)據(jù)for(ExportDataModel edm : mapData.get(tblName)){buffer.append(edm.getProductId()+","+edm.getPrice()+","+edm.getAmount()+"\n");}}//3:接著來拼接文件尾的內(nèi)容buffer.append(efm.getExportUser());//為了演示簡(jiǎn)潔性,這里就不去寫輸出文件的代碼了//把要輸出的內(nèi)容輸出到控制臺(tái)看看System.out.println("輸出到文本文件的內(nèi)容:\n"+buffer);} } /*** 導(dǎo)出數(shù)據(jù)到XML文件的對(duì)象*/ public class ExportToXml {/*** 導(dǎo)出數(shù)據(jù)到XML文件* @param ehm 文件頭的內(nèi)容* @param mapData 數(shù)據(jù)的內(nèi)容* @param efm 文件尾的內(nèi)容*/public void export(ExportHeaderModel ehm,Map<String,Collection<ExportDataModel>> mapData,ExportFooterModel efm){//用來記錄最終輸出的文件內(nèi)容StringBuffer buffer = new StringBuffer();//1:先來拼接文件頭的內(nèi)容buffer.append("<?xml version='1.0' encoding='gb2312'?>\n");buffer.append("<Report>\n");buffer.append(" <Header>\n");buffer.append(" <DepId>"+ehm.getDepId()+"</DepId>\n");buffer.append(" <ExportDate>"+ehm.getExportDate()+"</ExportDate>\n");buffer.append(" </Header>\n");//2:接著來拼接文件體的內(nèi)容buffer.append(" <Body>\n");for(String tblName : mapData.keySet()){//先拼接表名稱buffer.append(" <Datas TableName=\""+tblName+"\">\n");//然后循環(huán)拼接具體數(shù)據(jù)for(ExportDataModel edm : mapData.get(tblName)){buffer.append(" <Data>\n");buffer.append(" <ProductId>"+edm.getProductId()+"</ProductId>\n");buffer.append(" <Price>"+edm.getPrice()+"</Price>\n");buffer.append(" <Amount>"+edm.getAmount()+"</Amount>\n");buffer.append(" </Data>\n");}buffer.append(" </Datas>\n");}buffer.append(" </Body>\n");//3:接著來拼接文件尾的內(nèi)容buffer.append(" <Footer>\n");buffer.append(" <ExportUser>"+efm.getExportUser()+"</ExportUser>\n");buffer.append(" </Footer>\n");buffer.append("</Report>\n");//為了演示簡(jiǎn)潔性,這里就不去寫輸出文件的代碼了//把要輸出的內(nèi)容輸出到控制臺(tái)看看System.out.println("輸出到XML文件的內(nèi)容:\n"+buffer);} }

client端:

public static void main(String[] args) {//準(zhǔn)備測(cè)試數(shù)據(jù)ExportHeaderModel ehm = new ExportHeaderModel();ehm.setDepId("一分公司");ehm.setExportDate("2010-05-18");Map<String,Collection<ExportDataModel>> mapData = new HashMap<String,Collection<ExportDataModel>>();Collection<ExportDataModel> col = new ArrayList<ExportDataModel>();ExportDataModel edm1 = new ExportDataModel();edm1.setProductId("產(chǎn)品001號(hào)");edm1.setPrice(100);edm1.setAmount(80);ExportDataModel edm2 = new ExportDataModel();edm2.setProductId("產(chǎn)品002號(hào)");edm2.setPrice(99);edm2.setAmount(55); //把數(shù)據(jù)組裝起來col.add(edm1);col.add(edm2); mapData.put("銷售記錄表", col);ExportFooterModel efm = new ExportFooterModel();efm.setExportUser("張三");//測(cè)試輸出到文本文件ExportToTxt toTxt = new ExportToTxt();toTxt.export(ehm, mapData, efm);//測(cè)試輸出到xml文件ExportToXml toXml = new ExportToXml();toXml.export(ehm, mapData, efm); }

2. 用build模式,把頭、尾巴、中間三部分分開來

=>

代碼為

public interface Builder {/*** 構(gòu)建輸出文件的Header部分* @param ehm 文件頭的內(nèi)容*/public void buildHeader(ExportHeaderModel ehm);/*** 構(gòu)建輸出文件的Body部分* @param mapData 要輸出的數(shù)據(jù)的內(nèi)容*/public void buildBody(Map<String,Collection<ExportDataModel>> mapData);/*** 構(gòu)建輸出文件的Footer部分* @param efm 文件尾的內(nèi)容*/public void buildFooter(ExportFooterModel efm); } public class TxtBuilder implements Builder {/** * 用來記錄構(gòu)建的文件的內(nèi)容,相當(dāng)于產(chǎn)品 */private StringBuffer buffer = new StringBuffer();public void buildBody(Map<String, Collection<ExportDataModel>> mapData) {for(String tblName : mapData.keySet()){//先拼接表名稱buffer.append(tblName+"\n");//然后循環(huán)拼接具體數(shù)據(jù)for(ExportDataModel edm : mapData.get(tblName)){buffer.append(edm.getProductId()+","+edm.getPrice()+","+edm.getAmount()+"\n");}}}public void buildFooter(ExportFooterModel efm) {buffer.append(efm.getExportUser());}public void buildHeader(ExportHeaderModel ehm) {buffer.append(ehm.getDepId()+","+ehm.getExportDate()+"\n");} public StringBuffer getResult(){return buffer;} }public class XmlBuilder implements Builder {/*** 用來記錄構(gòu)建的文件的內(nèi)容,相當(dāng)于產(chǎn)品*/private StringBuffer buffer = new StringBuffer();public void buildBody(Map<String, Collection<ExportDataModel>> mapData) {buffer.append(" <Body>\n");for(String tblName : mapData.keySet()){//先拼接表名稱buffer.append(" <Datas TableName=\""+tblName+"\">\n");//然后循環(huán)拼接具體數(shù)據(jù)for(ExportDataModel edm : mapData.get(tblName)){buffer.append(" <Data>\n");buffer.append(" <ProductId>"+edm.getProductId()+"</ProductId>\n");buffer.append(" <Price>"+edm.getPrice()+"</Price>\n");buffer.append(" <Amount>"+edm.getAmount()+"</Amount>\n");buffer.append(" </Data>\n");}buffer.append(" </Datas>\n");}buffer.append(" </Body>\n");}public void buildFooter(ExportFooterModel efm) {buffer.append(" <Footer>\n");buffer.append(" <ExportUser>"+efm.getExportUser()+"</ExportUser>\n");buffer.append(" </Footer>\n");buffer.append("</Report>\n");}public void buildHeader(ExportHeaderModel ehm) {buffer.append("<?xml version='1.0' encoding='gb2312'?>\n");buffer.append("<Report>\n");buffer.append(" <Header>\n");buffer.append(" <DepId>"+ehm.getDepId()+"</DepId>\n");buffer.append(" <ExportDate>"+ehm.getExportDate()+"</ExportDate>\n");buffer.append(" </Header>\n");}public StringBuffer getResult(){return buffer;} }public class Director {/*** 持有當(dāng)前需要使用的構(gòu)建器對(duì)象*/private Builder builder;/*** 構(gòu)造方法,傳入構(gòu)建器對(duì)象* @param builder 構(gòu)建器對(duì)象*/public Director(Builder builder) {this.builder = builder;}/*** 指導(dǎo)構(gòu)建器構(gòu)建最終的輸出的文件的對(duì)象* @param ehm 文件頭的內(nèi)容* @param mapData 數(shù)據(jù)的內(nèi)容* @param efm 文件尾的內(nèi)容*/ public void construct(ExportHeaderModel ehm,Map<String,Collection<ExportDataModel>> mapData,ExportFooterModel efm) {//1:先構(gòu)建Headerbuilder.buildHeader(ehm);//2:然后構(gòu)建Bodybuilder.buildBody(mapData);//3:然后構(gòu)建Footerbuilder.buildFooter(efm);} }

3. 使用場(chǎng)景例子

保險(xiǎn)公司簽合同,有一些屬性需要檢查通過才可以,比如名稱要大于多少字符這些。

3.1 方法1: 在build函數(shù)里面檢查

public class ConcreteBuilder { //構(gòu)建真正的對(duì)象并返回 public InsuranceContract build(){if(contractId==null || contractId.trim().length()==0){throw new IllegalArgumentException("合同編號(hào)不能為空");}boolean signPerson = personName!=null && personName.trim().length()>0;boolean signCompany = companyName!=null && companyName.trim().length()>0;if(signPerson && signCompany){throw new IllegalArgumentException("一份保險(xiǎn)合同不能同時(shí)與人和公司簽訂");} if(signPerson==false && signCompany==false){throw new IllegalArgumentException("一份保險(xiǎn)合同不能沒有簽訂對(duì)象");}if(beginDate<=0){throw new IllegalArgumentException("合同必須有保險(xiǎn)開始生效的日期");}if(endDate<=0){throw new IllegalArgumentException("合同必須有保險(xiǎn)失效的日期");}if(endDate<=beginDate){throw new IllegalArgumentException("保險(xiǎn)失效的日期必須大于保險(xiǎn)生效日期");} return new InsuranceContract(this);}public static void main(String[] args) {//創(chuàng)建構(gòu)建器ConcreteBuilder builder = new ConcreteBuilder("001",12345L,67890L);//設(shè)置需要的數(shù)據(jù),然后構(gòu)建保險(xiǎn)合同對(duì)象InsuranceContract contract = builder.setPersonName("張三").setOtherData("test").build();//操作保險(xiǎn)合同對(duì)象的方法contract.someOperation(); }

3.2 內(nèi)聯(lián)類:

  • 構(gòu)建器為了創(chuàng)建被構(gòu)建的對(duì)象,不用單獨(dú)一個(gè)類, 將類內(nèi)聯(lián)化(Inline Class)放到這里來, 即是把構(gòu)建器對(duì)象合并到被構(gòu)建對(duì)象里面去。
public class InsuranceContract {...public static class ConcreteBuilder {..}}public static void main(String[] args) {//創(chuàng)建構(gòu)建器InsuranceContract.ConcreteBuilder builder = new InsuranceContract.ConcreteBuilder("001",12345L,67890L);//設(shè)置需要的數(shù)據(jù),然后構(gòu)建保險(xiǎn)合同對(duì)象InsuranceContract contract = builder.setPersonName("張三").setOtherData("test").build();//操作保險(xiǎn)合同對(duì)象的方法contract.someOperation();}

總結(jié)

以上是生活随笔為你收集整理的《研磨设计模式》chap8 生成器模式Builder的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。