源碼地址 | https://github.com/DingMouRen/DesignPattern |
---|
定義
構(gòu)建者模式將一個(gè)復(fù)雜對(duì)象的構(gòu)建與它的表示分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示解幽。
問題:構(gòu)造者模式和工廠模式都可以創(chuàng)建對(duì)象,區(qū)別在哪里?
1.建造者模式是讓建造者類來負(fù)責(zé)對(duì)象的創(chuàng)建工作,工廠模式是由工廠類來負(fù)責(zé)對(duì)象創(chuàng)建的工作
2.建造者模式是用來創(chuàng)建一種類型的復(fù)雜對(duì)象她倘,通過設(shè)置不同的可選參數(shù)埂奈,“定制化”的創(chuàng)建不同的對(duì)象;工廠模式是用來創(chuàng)建不同但是相同類型的對(duì)象(繼承同一父類或接口的一組子類)省有。
為什么需要構(gòu)建者模式?
1.構(gòu)造函數(shù)的參數(shù)列表會(huì)變得很長(zhǎng)谴麦,代碼在可讀性和易用性上都會(huì)變得很差蠢沿,在使用構(gòu)造函數(shù)的時(shí)候,很容易搞錯(cuò)各參數(shù)的順序匾效,參數(shù)可能傳遞錯(cuò)誤舷蟀,導(dǎo)致非常隱蔽的bug.
2.通過set()函數(shù)的弊端:1.參數(shù)項(xiàng)有一定的依賴關(guān)系,不適合 2.如果我們需要類對(duì)象是不可變對(duì)象,那么創(chuàng)建好后就不能修改屬性值了野宜,不能暴露set()函數(shù)
構(gòu)建者模式創(chuàng)建流程
把校驗(yàn)邏輯放置到 Builder 類中扫步,先創(chuàng)建建造者,并且通過 set() 方法設(shè)置建造者的變量值匈子,然后在使用 build() 方法真正創(chuàng)建對(duì)象之前河胎,做集中的校驗(yàn),校驗(yàn)通過之后才會(huì)創(chuàng)建對(duì)象虎敦。除此之外仿粹,我們把 ResourcePoolConfig 的構(gòu)造函數(shù)改為 private私有權(quán)限。這樣我們就只能通過建造者來創(chuàng)建 ResourcePoolConfig 類對(duì)象原茅。并且吭历,ResourcePoolConfig 沒有提供任何 set() 方法,這樣我們創(chuàng)建出來的對(duì)象就是不可變對(duì)象了擂橘。
成員變量 | 解釋 | 是否必填晌区? | 默認(rèn)值 |
---|---|---|---|
name | 資源名稱 | 是 | 沒有 |
maxTotal | 最大總資源數(shù) | 否 | 8 |
maxIdle | 最大空閑資源數(shù)量 | 否 | 8 |
minIdle | 最小空閑資源數(shù)量 | 否 | 0 |
public class ResourcePoolConfig {
private String name;
private int maxTotal;
private int maxIdle;
private int minIdle;
private ResourcePoolConfig(Builder builder){
this.name = builder.name;
this.maxTotal = builder.maxTotal;
this.maxIdle = builder.maxIdle;
this.minIdle = builder.minIdle;
}
public static class Builder{
private static final int DEFAULT_MAX_TOTAL = 8;
private static final int DEFAULT_MAX_IDLE = 8;
private static final int DEFAULT_MIN_IDLE = 0;
private String name;
private int maxTotal = DEFAULT_MAX_TOTAL;
private int maxIdle = DEFAULT_MAX_IDLE;
private int minIdle = DEFAULT_MIN_IDLE;
// 校驗(yàn)邏輯放在這里來做,包括必填項(xiàng)校驗(yàn)通贞、依賴關(guān)系校驗(yàn)朗若、約束條件校驗(yàn)等
public ResourcePoolConfig build(){
if (name.length() <= 0){
throw new IllegalArgumentException("...");
}
if (maxIdle > maxTotal){
throw new IllegalArgumentException("...");
}
if (minIdle > maxIdle || minIdle > maxTotal){
throw new IllegalArgumentException("...");
}
return new ResourcePoolConfig(this);
}
public Builder setName(String name){
if (maxTotal <= 0) {
throw new IllegalArgumentException("...");
}
this.name = name;
return this;
}
public Builder setMaxTotal(int maxTotal){
if (maxTotal <= 0){
throw new IllegalArgumentException("...");
}
this.maxTotal = maxTotal;
return this;
}
public Builder setMaxIdle(int maxIdle){
if (maxIdle < 0){
throw new IllegalArgumentException("...");
}
this.maxIdle = maxIdle;
return this;
}
public Builder setMinIdle(int minIdle){
if (minIdle < 0){
throw new IllegalArgumentException("...");
}
this.minIdle = minIdle;
return this;
}
}
}
public class Client {
public static void main(String[] args) {
ResourcePoolConfig config = new ResourcePoolConfig.Builder()
.setName("sdfs")
.setMaxIdle(5)
.build();
}
}