转载:http://blog.csdn.net/krislight/article/details/24850865
场景:
考虑导出数据的应用框架,通常在导出的数据形式上有一定的约定方式,对于不同的输出格式,处理步骤都是一样的,但
是每步的具体实现是不一样的,像导出成TXT和EXCEL的文本形式不一样,但是导出的数据都会分为文件头,文件体和文件
尾.所以应该将处理步骤导出文件头,导出文件体,导出文件尾这几个固定步骤提炼出来,形成公共的处理过程.今后可能会
有很多种不同输出格式的要求,这就需要在处理过程不变的情况下,能方便地切换不同的输出格式处理。
定义:
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
角色:
Builder:
生成器接口,定义创建一个Product对象所需的各个部件的操作。
package com.kris.study;
public interface Builder {
public void builderHead();
public void buidlerFoot();
public void buildPart();
}
ConcreteBuilder:
具体的生成器实现,实现各个部件的创建,并负责组装Product对象的各个部件,同时还提供一个让用户获取组装完成后
的产品对象的方法.
package com.kris.study;
public class ConcreteBuilder implements Builder {
/**
* 生成器最终构建的产品对象
*/
private Product resultProduct;
public Product getResult(){
return resultProduct;
}
@Override
public void buildPart() {
//构建某个部件的功能处理
System.out.println("创建身体");
}
@Override
public void builderHead() {
System.out.println("创建头部");
}
@Override
public void buidlerFoot() {
System.out.println("创建腿部");
}
}
package com.kris.study;
public class ConcreteBuilder2 implements Builder {
/**
* 生成器最终构建的产品对象
*/
private Product resultProduct;
public Product getResult(){
return resultProduct;
}
@Override
public void builderHead() {
System.out.println("创建触角");
}
@Override
public void buidlerFoot() {
System.out.println("创建躯干");
}
@Override
public void buildPart() {
System.out.println("创建脚");
}
}
Director:
指导者,主要用来使用Builder接口,以一个统一的过程来构建所需要的Product对象
package com.kris.study;
public class Director {
//持有当前需要使用的生成器对象
private Builder builder;
public Director(Builder builder){
this.builder = builder;
}
/**
* 指导生成器构建最终的产品对象
*/
public void construct(){
builder.builderHead();
builder.buildPart();
builder.buidlerFoot(); }}
Product:
产品,表示生成构建的复杂对象,包含多个部件。
public interface Product { //定义产品的操作 public String foot(); public String head(); public String body(); }
Client:
客户端
原理分析:
生成器模式的主要功能是构建复杂的产品,而且是细化的,分多个固定步骤构建的产品,这个构建的过程是统一的,不变的.
将变化的部分放到生成器部分,只有配置不同的生成器,那么同样的构建过程,就能构建出不同的产品来。
生成器两个很重要的部分:
1.Builder接口,这里定义了如何构建各个部件,也就是知道每个部件的功能如何实现,以及如何装配这些产品
2.Director指导者,Director负责整体的构建算法,知道如何组合来构建完整的产品.
在Director实现整体构建算法时,遇到需要创建和组合具体部件时,就会委托给Builder完成。
在实际应用中需要指导者Director和生成器Builder之间进行交互来构建产品,方式通过生成器方法的参数和返回值,来
回地传递数据。
采用Builder直接构建复杂的对象,通常会对Builder模式进行一定的简化.
1.由于是用Builder模式来创建某个对象,因此没必要再定义一个Builder接口,提供一个具体构建器类就可以了。
2.将指导者和Client功能合并起来,由Client去指导构建器去构造复杂对象
3.将构建器和被构建对象合并,将类内联化。
考虑一个实际应用,要创建一个合同对象,里面有很多属性值都有约束,要求创建出来的对象满足这些约束规则.约束规
则比如,保险合同通常情况下可以和个人签订,也可以和某个公司签订,但是一份合同不能同时与个人和公司签订。
package com.kris.study;
public class InsuranceContract {
private String contractId;
private String personName;
private String companyName;
private long beginDate;
private long endDate;
private String otherData;
private InsuranceContract(ConcreteBuilder builder){
contractId = builder.contractId;
personName = builder.personName;
companyName = builder.companyName;
beginDate = builder.beginDate;
endDate = builder.endDate;
otherData = builder.otherData;
}
public static class ConcreteBuilder{
private String contractId;
private String personName;
private String companyName;
private long beginDate;
private long endDate;
private String otherData;
public ConcreteBuilder(String contractId, long beginDate, long endDate) {
super();
this.contractId = contractId;
this.beginDate = beginDate;
this.endDate = endDate;
}
public ConcreteBuilder setPersonName(String personName) {
this.personName = personName;
return this;
}
public ConcreteBuilder setCompanyName(String companyName) {
this.companyName = companyName;
return this;
}
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(signCompany && signPerson){
throw new IllegalArgumentException("一份合同不能同时与人和公司签订");
}
if(signCompany == false && signPerson == false){
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 void someOperation(){
System.out.println("Now in Insurance Contract someOperation =="+this.contractId);
}
}
package com.kris.study;
public class Client {
public static void main(String[] args) {
InsuranceContract.ConcreteBuilder builder =
new InsuranceContract.ConcreteBuilder("101", 102L, 67890L);
InsuranceContract contract = builder.setPersonName("张三").
setOtherData("test").build();
contract.someOperation();
}
}
优点:
松散耦合,更好的复用性,将构建算法和具体产品实现分离,这样使得构建产品的算法可以复用。
本质: 分离整体构建算法和部件构造