Java 设计模式之 生成器模式(Builder)
2011-06-15 22:49:37| 分类: Java 设计模式 | 标签:java 设计模式之 生成器模式(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();
@Override
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());
}
}
● 使用生成器模式创建复杂对象:
① 由于使用Builder 模式来创建某个对象,因此就没有必要再定义一个Builder接口,直接提供一个具体的构建器类就可以了。
② 对于创建一个复杂的对象,可能会有很多种不同的选择和步骤,干脆去掉“Director”,把Director的功能和Client 的功能合并起来,也就是说这个时候,Client 相当于指导者,它来指导构建器类去构建需要的复杂对象。
public class ConcreteBuilder {
private String contractId;
private String personName;
private String companyName;
private long beginDate;
private long endDate;
private String otherData;
/**
* 构造方法 传入必填数据
* @param contractId 保险合同号
* @param beginDate 保险开始生效的日期
* @param endDate 保险失效的日期
*/
public ConcreteBuilder(String contractId, long beginDate, long endDate){
this.contractId = contractId;
this.beginDate = beginDate;
this.endDate = endDate;
}
/**
* 选填数据,被保险人
* @param personName 被保险人名
* @return 构建对象
*/
public ConcreteBuilder setPersonName(String personName){
this.personName = personName;
return this;
}
/**
* 选填数据,被保险公司
* @param companyName 被保险公司名
* @return 构建对象
*/
public ConcreteBuilder setCompanyName(String companyName){
this.companyName = companyName;
return this;
}
/**
* 选填数据,其它数据
* @param otherData 其它数据
* @return 构建对象
*/
public ConcreteBuilder setOtherData(String otherData){
this.otherData = otherData;
return this;
}
public InsuranceContract build(){
if(contractId == null || contractId.trim().length() == 0){
throw new IllegalArgumentException("合同编号不能空!");
}
boolean signPerson = (personName != null && personName.trim().length() > 0);
boolean signCompany = (companyName != null && companyName.trim().length() > 0);
if(!(signPerson ^ signCompany)){
throw new IllegalArgumentException("一份保险不能没有签订对象,且不能同时与人和公司签订!");
}
if(beginDate <= 0){
throw new IllegalArgumentException("合同必须有保险开始生效的日期!");
}
if(endDate <= 0){
throw new IllegalArgumentException("合同必须有保险失效的日期!");
}
if(endDate <= beginDate){
throw new IllegalArgumentException("保险失效日期必须大于生效日期!");
}
return new InsuranceContract(this);
}
public String getContractId() {
return contractId;
}
public String getPersonName() {
return personName;
}
public String getCompanyName() {
return companyName;
}
public long getBeginDate() {
return beginDate;
}
public long getEndDate() {
return endDate;
}
public String getOtherData() {
return otherData;
}
}
/**
* 保险合同对象
* @author joe
*
*/
public class InsuranceContract {
/**
* 保险合同编号
*/
private String constractId;
/**
* 被保险的人
*/
private String personName;
/**
* 被保险的公司
*/
private String companyName;
/**
* 保险开始生效的日期
*/
private long beginDate;
/**
* 保险失效的日期
*/
private long endDate;
/**
* 其它数据
*/
private String otherData;
/**
* 构造方法,访问级别是同包能访问
* @param builder
*/
InsuranceContract(ConcreteBuilder builder){
this.constractId = builder.getContractId();
this.personName = builder.getPersonName();
this.companyName = builder.getCompanyName();
this.beginDate = builder.getBeginDate();
this.endDate = builder.getEndDate();
this.otherData = builder.getOtherData();
}
public void someOperation(){
System.out.println("Now in Insurance Contract someOperation == " + this.constractId);
}
}
public class Client {
public static void main(String[] args) {
ConcreteBuilder builder = new ConcreteBuilder("001", 82345L, 67890L);
InsuranceContract contract = builder.setPersonName("张三").setOtherData("test").build();
contract.someOperation();
}
}
相关推荐
生成器模式(Builder Pattern)是一种设计模式,它允许我们分步骤构建复杂对象,而无需暴露其构造过程。这种模式在创建对象时提供了更大的灵活性,特别是当构造过程需要多个步骤或者对象有不同的构造方式时。Builder...
生成器模式(Builder Pattern)是一种创造型设计模式,它将一个复杂对象的构建与它的表示分离,使得同样的构建可以创建不同的表示。这种模式可以在以下情况下使用: 1. 当创建复杂对象的算法应该独立于该对象的组成...
生成器模式(Builder Pattern)是Java设计模式中的创建型模式之一,主要解决复杂对象的构建问题,通过将构造过程逐步分解,使得构造过程与表示分离,使得同样的构建过程可以创建不同的表示。这种模式通常用于创建...
" JAVA 设计模式概述" JAVA 设计模式是指在软件设计过程中,为了提高代码的可维护性、灵活性和可扩展性所使用的一些惯用解决方案。JAVA 设计模式可以分为三种:创建模式、结构模式和行为模式。 1. 创建模式 创建...
在《Java设计模式》这本书的模拟试题及其参考答案中,涉及了多条设计模式的知识点,以及它们的应用场景和实现方法。现在将这些知识点详细地解释如下: 1. 开闭原则(Open-Closed Principle, OCP): 开闭原则是面向...
FreeBuilder为 Java 1.6 自动生成 Builder 模式。当设计类的构造函数或静态工厂具有多个参数时,Builder 模式是一个不错的选择。—— Effective Java,第二版,第39页背景在 Java 中实现 Builder 模式容易出错和...
生成器模式(Builder)是使用多个“小型”工厂来最终创建出一个完整对象。当我们使用Builder的时候,一般来说,是因为创建这个对象的步骤比较多,每个步骤都需要一个零部件,最终组合成一个完整的对象。 Builder...
### Java设计模式详解 #### 一、引言 自从J2EE(Java 2 Enterprise Edition)的出现,Java的企业级应用程序开发得到了极大的简化。然而,随着J2EE在各行各业中的广泛应用,开发人员逐渐意识到需要一种更为系统化的...
### Java设计模式与原理 #### 一、概述 在软件工程领域,设计模式是指在特定情境下解决软件设计问题的最佳实践。《Java 设计模式与原理》这本书被誉为Java程序员的必备指南之一,它深入浅出地讲解了23种经典的设计...
Java设计模式是软件开发中的重要概念,源自于“Gang of Four”(GoF)的经典著作《设计模式:可复用面向对象软件的基础》。这些模式代表了在编写可维护和扩展的Java应用时,经过时间和实践验证的最佳实践。张跃平和...
### JAVA设计模式详解 #### 一、引言:学习GOF设计模式的重要性 设计模式是在软件工程领域中解决常见问题的一系列解决方案。Gang of Four(GOF)的经典著作《设计模式:可复用面向对象软件的基础》为软件开发者...
生成器模式是一种设计模式,属于创建型模式,它允许我们分步骤构建复杂对象,而无需提前知道整个对象的完整结构。这种模式的核心在于延迟初始化,它使得我们可以根据需要逐步构建对象,而不是一次性创建所有部分。在...
《JAVA设计模式》是一本深入探讨Java编程中设计模式的宝贵资源。设计模式是软件开发中的通用解决方案,它们是经过时间验证的、在特定场景下解决问题的最佳实践。这本书的.chm格式表明它可能是一个帮助文件或电子书,...
Java设计模式是软件开发中的重要概念,它是一种在特定情境下解决常见问题的经验总结,能够提升代码的可读性、可维护性和复用性。本资料包“java设计模式源码和笔记(第一部分)”提供了对Java设计模式的深入理解和...
在"Java设计模式之创建型模式源码以及文档"中,你将找到这些模式的具体实现,包括源码和相关文档。通过阅读源码,你可以深入理解每种模式的内部工作机制,而文档则会提供理论背景和应用场景的解释,帮助你更好地运用...
文件可能还包含了Builder模式与其他设计模式(如工厂模式、抽象工厂模式)的对比,以及如何在Java、C#等编程语言中使用Builder模式的示例代码。通过学习这个文件,可以深入理解Builder模式,并掌握如何在项目中有效...
### JAVA23中设计模式详解 #### 一、概述 设计模式是在软件设计过程中解决常见问题的一套可复用的解决方案。《JAVA23中设计模式》是一份针对Java程序员的指南,旨在通过一系列示例和理论讲解,帮助读者理解和掌握...
### Java设计模式之现实实例讲解 #### 一、概述 设计模式是在软件开发过程中,针对常见问题而总结出的一系列经过验证的解决方案。通过学习设计模式,开发者可以更好地理解和解决实际编程中的各种挑战,提高代码的...