场景问题
在讨论工厂方法模式的时候,我们提到了一个导出数据的应用框架,对于导出数据的应用框架,通常在导出数据上面=,会有一些特定的方式,比如导出的文本格式,xml格式,在上节中,我们只考虑了如何选择具体导出方案,并没有涉及任何实现,如果我们现在对于导出数据的格式有如下要求
- 导出的文件,不管什么格式,都有三个部分,即头文件,文件体和文件尾
- 在文件头部分,有以下描述信息:分公司和门市点编号,导出数据的格式,对于文本格式,中间要用逗号分离
- 在文件体部分,需要以下信息,表名称
- 文件尾部分需要输出人
不同模式下的解决方案
由此我们可以想像出,不管是输出为文本文件还是xml文件,步骤基本是一样的,即
- 拼接文件头的内容
- 拼接文件体的内容
- 在拼接文件尾的内容
- 最后把拼接的内容输出为文件
即对于不同的输出格式,处理的步骤是一样的,只是每步实现的方式是不一样的,按照现在的方式,就会存在几个问题,例如,构建每一种输出格式的内容的时候,都会重复这几个处理步骤,应该提炼出来形成公共处理过程,今后可能会要求很多种不同的输出格式,这就需要在处过程不变的情况下方便的切换不同的输出格式
解决方案
上述问题的一个合理的解决方案就是生成器模式
定义
将一个复杂的对象的构建与他的表示分离,使得同样的构建过程可以创建不同的表示
例子
/**
* @Author: 谭婧杰
* 描述数据输出对象
*/
public class ExportDataModel {
private String productId;
private double price;
public String getProductId() {
return productId;
}
public void setProductId(String productId) {
this.productId = productId;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public double getAmount() {
return amount;
}
public void setAmount(double amount) {
this.amount = amount;
}
private double amount;
}
/**
* 描述输出到文件尾内容
* @Author: 谭婧杰
*/
public class ExportFooterModel {
public String getExportUser() {
return exportUser;
}
public void setExportUser(String exportUser) {
this.exportUser = exportUser;
}
private String exportUser;
}
/**
* @Author: 谭婧杰
* 描述道文件头的内容
*/
public class ExportHeaderModel {
private String depId;
public void setDepId(String depId) {
this.depId = depId;
}
public void setExportDate(String exportDate) {
this.exportDate = exportDate;
}
public String getDepId() {
return depId;
}
public String getExportDate() {
return exportDate;
}
private String exportDate;
}
import java.util.Collection;
import java.util.Map;
/**
* @Description: 生成器接口
* @Author: 谭婧杰
*/
public interface Builder {
/**
* 构建部件 head部分
*/
void buildHeader(ExportHeaderModel ehm);
void buildBody(Map<String, Collection<ExportDataModel>> mapData);
void buildFooter(ExportFooterModel efm);
}
import java.util.Collection;
import java.util.Map;
/**
* 指导者 指导使用生成器的接口来构建输出文件
* @Author: 谭婧杰
*/
public class Director {
private Builder builder;
public Director(Builder builder) {
this.builder = builder;
}
public void construct(ExportHeaderModel ehm,
Map<String, Collection<ExportDataModel>> mapData,
ExportFooterModel efm
){
builder.buildHeader(ehm);
builder.buildBody(mapData);
builder.buildFooter(efm);
}
}
import java.util.Collection;
import java.util.Map;
/**
* 实现导出数据到文本文件生成器对象
* @Author: 谭婧杰
*/
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());
}
}
/**
* 被构建对象的接口
* @Author: 谭婧杰
*/
public interface Product {
}
import java.util.*;
/**
* @Author: 谭婧杰
*/
public class Client {
public static void main(String[] args) {
ExportHeaderModel ehm = new ExportHeaderModel();
ehm.setDepId("一分公司");
ehm.setExportDate("2010-07-19");
Map<String, Collection<ExportDataModel>> mapData = new HashMap<String, Collection<ExportDataModel>>();
Collection<ExportDataModel> col = new ArrayList<ExportDataModel>();
ExportFooterModel efm = new ExportFooterModel();
efm.setExportUser("张三");
ExportDataModel edm1 = new ExportDataModel();
edm1.setProductId("产品001号");
edm1.setPrice(100);
edm1.setAmount(80);
TxtBuilder txtBuilder = new TxtBuilder();
Director director = new Director(txtBuilder);
director.construct(ehm,mapData,efm);
System.out.println();
}
}
模式详解
生成器模式主要功能是构建复杂的产品,而是细化,分步骤的构建产品,也就是生成器模式重在一步一步解决构造复杂对象的问题