设计模式之----建造者模式

建造者模式

抽象建造者(Builder)角色:给 出一个抽象接口,以规范产品对象的各个组成成分的建造。一般而言,此接口独立于应用程序的商业逻辑。模式中直接创建产品对象的是具体建造者 (ConcreteBuilder)角色。具体建造者类必须实现这个接口所要求的两种方法:一种是建造方法(buildPart1和 buildPart2),另一种是返还结构方法(retrieveResult)。一般来说,产品所包含的零件数目与建造方法的数目相符。换言之,有多少 零件,就有多少相应的建造方法。
  
  导演者(Director)角色:担任这个角色的类调用具体建造者角色以创建产品对象。应当指出的是,导演者角色并没有产品类的具体知识,真正拥有产品类的具体知识的是具体建造者角色。
  
  产品(Product)角色:产品便是建造中的复杂对象。一般来说,一个系统中会有多于一个的产品类,而且这些产品类并不一定有共同的接口,而完全可以是不相关联的。

一般来说,每有一个产品类,就有一个相应的具体建造者类。这些产品应当有一样数目的零件,而每有一个零件就相应地在所有的建造者角色里有一个建造方法

要创建一个保险合同的对象,里面很多属性的值都有约束,要求创建出来的对象是满足这些约束规则的。
约束规则如下:
a.保险合同通常情况下可以和个人签订,也可以和某个公司签订,但是一份保险合同不能同时与个人和公司签订。
b.保险失效日期,一定会大于保险开始生效日期
c.一份保险合同必须有生效的日期
d.一份保险合同必须有失效的日期
e.一份保险合同必须有保险对象
f.一份保险合同必须有保险编号
采用建造模式来构建复杂的对象,通常会对建造模式进行一定的简化,因为目标明确,就是创建某个复杂对象,因此做适当简化会使程序更简洁。大致简化如下:
● 由于是用Builder模式来创建某个对象,因此就没有必要再定义一个Builder接口,直接提供一个具体的建造者类就可以了。
  ● 对于创建一个复杂的对象,可能会有很多种不同的选择和步骤,干脆去掉“导演者”,把导演者的功能和Client的功能合并起来,也就是说,Client这个时候就相当于导演者,它来指导构建器类去构建需要的复杂对象。

在本例中将具体建造者合并到了产品对象中,并将产品对象的构造函数私有化,防止客户端不使用构建器来构建产品对象,而是直接去使用new来构建产品对象所导致的问题。另外,这个构建器的功能就是为了创建被构建的对象,完全可以不用单独一个类。
 图片引用自博客
在这里插入图片描述

package insuranceContract;

import java.text.SimpleDateFormat;
import java.util.Date;

import builder.InsuranceBuilder;

/**
 *  保险合同类
 */

public class InsuranceContract {
	//以下二者不能同时参与保险
	private String personName;//被保险人姓名
	private String companyName;//被保险公司名称
	
	private String id;//保险合同编号
	private Date startDate;//生效日期
	private Date endDate;//失效时间
	
	public InsuranceContract(InsuranceBuilder builder){
		this.id = builder.getId();
		this.personName = builder.getPersonName();
		this.companyName = builder.getCompanyName();
		this.startDate = builder.getStartDate();
		this.endDate = builder.getEndDate();
	}
	
	
	public void createInsurance(){
		System.out.println("当前保险合同编号为:"+this.id);
		if(personName != null){
			System.out.println("被保险人姓名:"+personName);
		}else if(companyName != null){
			System.out.println("被保险公司名称:"+companyName);
		}
		SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd");
		System.out.println("当前保险合同生效日期:"+sdf.format(startDate));
		System.out.println("当前保险合同失效日期:"+sdf.format(endDate));
	}
}
package builder;

import insuranceContract.InsuranceContract;
import java.util.Date;

/**
 * 具体建造类
 */
public class InsuranceBuilder {
	private String personName;// 被保险人姓名
	private String companyName;// 被保险公司名称

	private String id;// 保险合同编号
	private Date startDate;// 生效日期
	private Date endDate;// 失效时间

	public InsuranceBuilder(String id, Date startDate, Date endDate) {
		this.id = id;
		this.startDate = startDate;
		this.endDate = endDate;
	}

	public InsuranceBuilder setPersonName(String personName) {
		this.personName = personName;
		return this;
	}

	public InsuranceBuilder setCompanyName(String companyName) {
		this.companyName = companyName;
		return this;
	}

	public InsuranceContract create() {
			if (id.equals("") || id.trim().length() == 0) {
				throw new IllegalArgumentException("保险合同编号不能为空!");
			}
			if (personName == null && companyName == null) {
				throw new IllegalArgumentException("一份保险的签订对象不能为空!");
			}
			if(personName != null && companyName != null){
				throw new IllegalArgumentException("一份保险不能同时与个人和公司签订!"); 
			}
			if (startDate == null) {
				throw new IllegalArgumentException("一份保险必须有生效日期!");
			}
			if (endDate == null) {
				throw new IllegalArgumentException("一份保险必须有失效日期!");
			}
			if (endDate.compareTo(startDate) <= 0) {
				throw new IllegalArgumentException("一份保险失效日期必须大于生效日期!");
			}
		 
		return new InsuranceContract(this);
	}

	public String getId() {
		return id;
	}
	public Date getStartDate() {
		return startDate;
	}
	public Date getEndDate() {
		return endDate;
	}
	public String getPersonName() {
		return personName;
	}
	public String getCompanyName() {
		return companyName;
	}

}
package client;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import builder.InsuranceBuilder;
import insuranceContract.InsuranceContract;

/**
 * 客户端类
 */
public class Client {
	public static void main(String[] args){
		SimpleDateFormat format= new SimpleDateFormat("yyyy-MM-dd");
		Date startDate = null,endDate = null;
		try {
			startDate = format.parse("2018-10-24");
			endDate = format.parse("2020-10-24");
		} catch (ParseException e) {
			e.printStackTrace();
		}
		InsuranceBuilder builder = new InsuranceBuilder("1001", startDate, endDate);
		builder.setPersonName("张三");
		//builder.setCompanyName("苹果公司");
		
		InsuranceContract contract = builder.create();
		contract.createInsurance();
		
	}
}

运行结果

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Felix_ar/article/details/83618460