1. 程式人生 > >設計模式之----建造者模式

設計模式之----建造者模式

建造者模式

抽象建造者(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();
		
	}
}

執行結果

在這裡插入圖片描述