跟屌絲大哥學習設計模式--生成器模式(Builder)
Builder 模式的重心在于分離構建算法和具體的構造實現,從而使構建算法可以重用。
Builder 模式的構成分為兩部分:一部分是Builder接口,定義了如何構建各個部件,并裝配到產品中去;另一部分是Director,定義如何來構建產品,Director 負責整體的構建算法,而且通常是分步來執行的。
注:這里的構建算法是指:通過什么樣的方式來組裝產品;構建產品指的是:構建一個復雜對象。
Builder 模式就是將構建產品部件和組裝產品的過程分開,即實現了產品部件和組裝產品過程的解耦,可以使得組裝產品過程得到復用
public class ExportHeaderModel {
private String depId;
private String exportDate;
省略getter 和 setter
}
public class ExportDataModel {
private String productId;
private double price;
private double amount;
省略getter 和 setter
}
public class ExportFooterModel {
private String exportUser;
省略getter 和 setter
}
/**
* 生成器接口,定義一個輸出文件對象所需的各個部件的操作
*
*/
public interface Builder {
/**
* 構建輸出文件的Header部分
* @param ehm 文件頭的內容
*/
public void buildHeader(ExportHeaderModel ehm);
/**
* 構建輸出文件的Body部分
* @param mapData 要輸出文件的數據內容
*/
public void buildBody(Map<String, Collection<ExportDataModel>> mapData);
/**
* 構建要輸出文件的Footer部分
* @param efm 文件尾的內容
*/
public void buildFooter(ExportFooterModel efm);
}
/**
* 實現導出數據到文本文件的生成器
*
*/
public class TxtBuilder implements Builder {
/**
* 用來記錄構建文件的內容,相當于產品
*/
private StringBuffer buffer = new StringBuffer();
@Override
public void buildHeader(ExportHeaderModel ehm) {
buffer.append(ehm.getDepId() + "," + ehm.getExportDate() + "\n");
}
@Override
public void buildBody(Map<String, Collection<ExportDataModel>> mapData) {
for(String tblName : mapData.keySet()){
buffer.append(tblName + "\n");
for(ExportDataModel edm : mapData.get(tblName)){
buffer.append(edm.getProductId() + "," + edm.getPrice() + "," + edm.getAmount() + "\n");
}
}
}
@Override
public void buildFooter(ExportFooterModel efm) {
buffer.append(efm.getExportUser());
}
public StringBuffer getResult(){
return buffer;
}
}
public class XmlBuilder implements Builder {
private StringBuffer buffer = new StringBuffer();
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");
}
@Override
public void buildBody(Map<String, Collection<ExportDataModel>> mapData) {
buffer.append(" <Body>\n");
for(String tblName : mapData.keySet()){
buffer.append(" <Datas TableName=\"" + tblName + "\">\n");
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");
}
@Override
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 StringBuffer getResult(){
return buffer;
}
}
/**
* 指導者,指導使用生成器的接口來構建輸出的文件對象
*
/**
* 指導者,指導使用生成器的接口來構建輸出的文件對象
*
*/
public class Director {
/**
* 持有當前需要使用的生成器對象
*/
private Builder builder;
public Director(Builder builder){
this.builder = builder;
}
/**
* 指導生成器構建最終的輸出文件的對象
* @param ehm 文件頭的內容
* @param mapData 數據的內容
* @param efm 文件尾的內容
*/
public void construct(ExportHeaderModel ehm, Map<String, Collection<ExportDataModel>> mapData,
ExportFooterModel efm){
//構建Header
builder.buildHeader(ehm);
//構建Body
builder.buildBody(mapData);
//構建Footer
builder.buildFooter(efm);
}
}
public class Client {
public static void main(String[] args) {
ExportHeaderModel ehm = new ExportHeaderModel();
ehm.setDepId("一分公司");
ehm.setExportDate("2011-06-12");
Map<String, Collection<ExportDataModel>> mapData = new HashMap<String, Collection<ExportDataModel>>();
Collection<ExportDataModel> coll = new ArrayList<ExportDataModel>();
ExportDataModel edml = new ExportDataModel();
edml.setAmount(80);
edml.setProductId("產品001號");
edml.setPrice(100);
coll.add(edml);
ExportDataModel edm2 = new ExportDataModel();
edm2.setAmount(60);
edm2.setProductId("產品002號");
edm2.setPrice(120);
coll.add(edm2);
mapData.put("銷售記錄表", coll);
ExportFooterModel efm = new ExportFooterModel();
efm.setExportUser("張三");
TxtBuilder txtBuilder = new TxtBuilder();
Director director = new Director(txtBuilder);
director.construct(ehm, mapData, efm);
System.out.println("輸出到文本文件的內容:\n" + txtBuilder.getResult());
XmlBuilder xmlBuilder = new XmlBuilder();
Director director2 = new Director(xmlBuilder);
director2.construct(ehm, mapData, efm);
System.out.println("輸出到Xml文件的內容:\n" + xmlBuilder.getResult());
}
}