建造者模式结构:
Builder:抽象建造者
ConcretBuilder:具体建造者
Director:指挥者
Product:具体产品
UML图:
例子代码:
普通建造者:
public interface Builder { void buildPartA(); void buildPartB(); void buildPartC(); Product getResult(); }
public class ConcreteBuilder implements Builder { Product product = new Product(); @Override public void buildPartA() { product.setPart1("编号:9527"); } @Override public void buildPartB() { product.setPart2("颜色:红色"); } @Override public void buildPartC() { product.setPart3("生产厂商:鸿基"); } @Override public Product getResult() { return product; } }
public class Director { private Builder pbuilder; public void construct(){ pbuilder.buildPartA(); pbuilder.buildPartB(); pbuilder.buildPartC(); } public void setBuilder(Builder builder){ pbuilder = builder; } }
public class Product { /** * 定义一些关于产品的操作 */ private String part1; private String part2; private String part3; public String getPart3() { return part3; } public void setPart3(String part3) { this.part3 = part3; } public String getPart1() { return part1; } public void setPart1(String part1) { this.part1 = part1; } public String getPart2() { return part2; } public void setPart2(String part2) { this.part2 = part2; } @Override public String toString() { return "最终产品组成:"+part1+" "+part2+" "+part3; } }
public class BuilderTest { public static void main(String[] args) { ConcreteBuilder builder = new ConcreteBuilder(); Director director = new Director(); director.setBuilder(builder); director.construct(); Product product = builder.getResult(); System.out.println(product.toString()); } }
集中建造者,一句代码即可配置建造模式:
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){ this.contractId = builder.contractId; this.personName = builder.personName; this.companyName = builder.companyName; this.beginDate = builder.beginDate; this.endDate = builder.endDate; this.otherData = builder.otherData; } /** * 保险合同的一些操作 */ public void someOperation(){ System.out.println("当前正在操作的保险合同编号为【"+this.contractId+"】"); } public static 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; } //被保险人员的名称 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; } /** * 构建真正的对象并返回 * @return 构建的保险合同对象 */ 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(signPerson == false && signCompany == 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 class InsuranceContractTest { public static void main(String[] args) { //创建构建器对象 InsuranceContract.ConcreteBuilder builder = new InsuranceContract.ConcreteBuilder("9527", 123L, 456L); //设置需要的数据,然后构建保险合同对象 InsuranceContract contract = builder.setCompanyName("xiao") .setOtherData("dd") .build(); //操作保险合同对象的方法 contract.someOperation(); } }