文档章节

生成器模式-创建型模式5

凯文加内特
 凯文加内特
发布于 2014/02/08 15:41
字数 1890
阅读 130
收藏 3

     生成器模式(英:Builder Pattern)是一种设计模式,又名:建造模式,是一种对象构建模式。它可以将复杂对象的建造过程抽象出来(抽象类别),使这个抽象过程的不同实现方法可以构造出不同表现(属性)的对象。

定义:

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

结构:

说明:

Builder:

       生成器接口,定义创建一个Product对象所需的各个部件的操作。

ConcreteBuilder:

       具体的生成器实现,实现各个部件的创建,并负责组装Product对象的各个部件,同时还提供一个让用户获取组装完成后的产品对象的方法。

Director:

       指导者,也被称为导向者,主要用来使用Builder接口,以一个统一的过程来构建所需要的Product对象。

Product:

       产品,表示被生成器构建的复杂对象,包含多个部件。

具体代码:

Builder接口:

/**
 * 类说明: 构建器接口,定义创建一个产品对象所需的各个部件的操作
 * Time: 2014-2-8 下午2:49:16 
 * @author 凯文加内特
 * Company: http://weibo.com/u/3165936675
 */

public interface Builder {
	/**
	 * 示意方法,构建某个部件
	 */
	public void buildPart();
}

ConcreteBuilder类:

/**
 * 类说明: 具体的构建器实现对象
 * Time: 2014-2-8 下午2:49:32 
 * @author 凯文加内特
 * Company: http://weibo.com/u/3165936675
 */

public class ConcreteBuilder implements Builder {
	/**
	 * 构建器最终构建的产品对象
	 */
	private Product resultProduct;

	/**
	 * 获取构建器最终构建的产品对象
	 * @return 构建器最终构建的产品对象
	 */
	public Product getResult() {
		return resultProduct;
	}

	public void buildPart() {
		//构建某个部件的功能处理
	}
}

Director类:

/**
 * 类说明: 指导者,指导使用构建器的接口来构建产品的对象
 * Time: 2014-2-8 下午2:50:36 
 * @author 凯文加内特
 * Company: http://weibo.com/u/3165936675
 */

public class Director {
	/**
	 * 持有当前需要使用的构建器对象
	 */
	private Builder builder;

	/**
	 * 构造方法,传入构建器对象
	 * @param builder 构建器对象
	 */
	public Director(Builder builder) {
		this.builder = builder;
	}

	/**
	 * 示意方法,指导构建器构建最终的产品对象
	 */
	public void construct() {
		//通过使用构建器接口来构建最终的产品对象
		builder.buildPart();
	}
}

Product类:

/**
 * 类说明: 被构建的产品对象的接口
 * Time: 2014-2-8 下午2:50:54 
 * @author 凯文加内特
 * Company: http://weibo.com/u/3165936675
 */

public interface Product {
	//定义产品的操作
}

具体案例:

导出文件到txt和xml

/**
 * 类说明: 描述输出到文件头的内容的对象
 * Time: 2014-2-8 下午2:53:05 
 * @author 凯文加内特
 * Company: http://weibo.com/u/3165936675
 */

public class ExportHeaderModel {
	/**
	 * 分公司或门市点编号
	 */
	private String depId;
	/**
	 * 导出数据的日期
	 */
	private String exportDate;

	public String getDepId() {
		return depId;
	}

	public void setDepId(String depId) {
		this.depId = depId;
	}

	public String getExportDate() {
		return exportDate;
	}

	public void setExportDate(String exportDate) {
		this.exportDate = exportDate;
	}
}
/**
 * 类说明: 描述输出数据的对象
 * Time: 2014-2-8 下午2:52:28 
 * @author 凯文加内特
 * Company: http://weibo.com/u/3165936675
 */

public class ExportDataModel {
	/**
	 * 产品编号
	 */
	private String productId;
	/**
	 * 销售价格
	 */
	private double price;
	/**
	 * 销售数量
	 */
	private double amount;

	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;
	}

}
/**
 * 类说明: 描述输出到文件尾的内容的对象
 * Time: 2014-2-8 下午2:52:49 
 * @author 凯文加内特
 * Company: http://weibo.com/u/3165936675
 */

public class ExportFooterModel {
	/**
	 * 输出人
	 */
	private String exportUser;

	public String getExportUser() {
		return exportUser;
	}

	public void setExportUser(String exportUser) {
		this.exportUser = exportUser;
	}

}
/**
 * 类说明: 构建器接口,定义创建一个输出文件对象所需的各个部件的操作
 * Time: 2014-2-8 下午2:51:37 
 * @author 凯文加内特
 * Company: http://weibo.com/u/3165936675
 */

import java.util.Collection;
import java.util.Map;

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);
}
/**
 * 类说明: 实现导出数据到文本文件的的构建器对象
 * Time: 2014-2-8 下午2:53:21 
 * @author 凯文加内特
 * Company: http://weibo.com/u/3165936675
 */

import java.util.Collection;
import java.util.Map;

public class TxtBuilder implements Builder {
	/**
	 * 用来记录构建的文件的内容,相当于产品
	 */
	private StringBuffer buffer = new StringBuffer();

	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");
			}
		}
	}

	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 {
	/**
	 * 用来记录构建的文件的内容,相当于产品
	 */
	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");
			//然后循环拼接具体数据
			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;
	}

}
/**
 * 类说明: 指导者,指导使用构建器的接口来构建输出的文件的对象
 * Time: 2014-2-8 下午2:52:14 
 * @author 凯文加内特
 * Company: http://weibo.com/u/3165936675
 */

public class Director {
	/**
	 * 持有当前需要使用的构建器对象
	 */
	private Builder builder;

	/**
	 * 构造方法,传入构建器对象
	 * @param 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) {
		//1:先构建Header
		builder.buildHeader(ehm);
		//2:然后构建Body
		builder.buildBody(mapData);
		//3:然后构建Footer
		builder.buildFooter(efm);
	}
}
/**
 * 类说明: 
 * Time: 2014-2-8 下午2:51:54 
 * @author 凯文加内特
 * Company: http://weibo.com/u/3165936675
 */

public class Client {
	public static void main(String[] args) {
		//准备测试数据
		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("产品001号");
		edm1.setPrice(100);
		edm1.setAmount(80);

		ExportDataModel edm2 = new ExportDataModel();
		edm2.setProductId("产品002号");
		edm2.setPrice(99);
		edm2.setAmount(55);
		//把数据组装起来
		col.add(edm1);
		col.add(edm2);
		mapData.put("销售记录表", col);

		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());
		//测试输出到xml文件
		XmlBuilder xmlBuilder = new XmlBuilder();
		Director director2 = new Director(xmlBuilder);
		director2.construct(ehm, mapData, efm);
		//把要输出的内容输出到控制台看看
		System.out.println("输出到XML文件的内容:\n" + xmlBuilder.getResult());

	}
}

使用场景:

当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时;

当构造过程必须允许被构造的对象有不同的表示时。

优点和缺点:

1.松散耦合,同一构建算法结构构建出表现完全不同的对象,实现对象构建跟对象表现上的分离;

2.很容易改变产品的内部表示,相对Director来说,产品内部变化不影响Director

3.复用,构建算法和具体实现都可以被复用

留给自己的问题:

与模板模式的区别,生成器模式是分离复杂对象的构建算法和具体实现,模板定义算法骨架,把某些步骤延迟到子类去实现

© 著作权归作者所有

凯文加内特
粉丝 341
博文 701
码字总数 110786
作品 0
青岛
后端工程师
私信 提问
Java设计模式:生成器模式

问题的提出: 有些类很容易创建对象,直接调用其构造方法,例如Student student = new Student(“1001”,”zhang”,21); 之所以容易创建,因为其类成员都是基本数据类型或者封装类,或者字符...

jjjyyy66
2017/05/15
0
0
不老呢做草药--建造者(Builder)模式

原创,转载请注明! 不老呢做草药,不论是做治痢疾的,还是治烧烫伤的,做草药的步骤是固定的,主要分这么几种: 1 采药; 2 烘干; 3 研磨; 4 混合; 于是,他总结了一个抽象的做草药办法-...

长平狐
2013/04/25
69
0
Java创建型模式的讨论

创建型模式抽象了实例化过程。它们帮助一个系统独立于如何创建、组合和表示它的那些对象。一个类创建型模式使用继承改变被实例化的类,而一个对象创建型模式将实例化委托给另一个对象。 创建...

tequliapop
2016/01/13
125
0
Builder设计模式

Builder模式,又称生成器或构建者模式,属于对象创建型模式,侧重于一步一步的构建复杂对象,只有在构建完成后才会返回生成的对象。Builder模式将一个复杂对象的构建与它的表示分离,使得同样...

Vincent-Duan
2016/10/24
13
0
Java 设计模式(16) —— 生成器模式

一、生成器模式 封装一个复杂对象构造过程,并允许按步骤构造 二、示例 度假计划生成项目:时间、门票、餐厅、住宿、特殊活动等,一个计划就是一个具体对象,要便于扩展 对于用户来说关心的只...

磊_lei
2018/05/29
0
0

没有更多内容

加载失败,请刷新页面

加载更多

75、GridFS

GridFS是MongoDB提供的用于持久化存储文件的模块,CMS使用Mongo DB存储数据,使用FGridFS可以快速集成开发。 工作原理: 在GridFS存储文件是将文件分块存储,文件会按照256KB的大小分割成多个...

lianbang_W
25分钟前
4
0
js bind 绑定this指向

本文转载于:专业的前端网站➱js bind 绑定this指向 1、示例代码 <!DOCTYPE html><html lang="zh"> <head> <meta charset="UTF-8" /> <title>bind函数绑定this指向......

前端老手
28分钟前
4
0
CentOS Linux 7上将ISO映像文件写成可启动U盘

如今,电脑基本上都支持U盘启动,所以,可以将ISO文件写到U盘上,用来启动并安装操作系统。 我想将一个CentOS Linux 7的ISO映像文件写到U盘上,在CentOS Linux 7操作系统上,执行如下命令: ...

大别阿郎
35分钟前
4
0
深入vue-公司分享ppt

组件注册 全局注册 注册组件,传入一个扩展过的构造器 Vue.component('my-component', Vue.extend({/*...*/})) 注册组件,传入一个选项对象(自动调用Vue.extend) Vue.component('my-comp...

莫西摩西
36分钟前
3
0
gitlab重置管理员密码

登录gitlab服务器 [root@localhost bin]# sudo gitlab-rails console productionLoading production environment (Rails 5.2.3)irb(main):001:0> u = User.where(email: 'admin@example.co......

King华仔o0
46分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部