activexobject对象不能创建_【设计模式】建造者模式:你创建对象的方式有它丝滑吗?...
目錄
- 什么是建造者模式
- 為什么要使用建造者模式
- 構(gòu)造函數(shù)創(chuàng)建對(duì)象
- set方式構(gòu)建對(duì)象
- java實(shí)現(xiàn)建造者模式
- 第一種實(shí)現(xiàn)方式
- 第二種方式
- 建造者模式與構(gòu)造函數(shù)的對(duì)比
- 建造者模式與工廠模式的對(duì)比
- 總結(jié)
什么是建造者模式
建造者模式是設(shè)計(jì)模式的一種,將一個(gè)復(fù)雜對(duì)象的構(gòu)建與它的表示分離,使得同樣的構(gòu)建過(guò)程可以創(chuàng)建不同的表示。
其實(shí)建造者模式是被翻譯過(guò)來(lái)的,他原名叫builder模式,也被稱(chēng)為生成器模式,這種模式的實(shí)現(xiàn)非常的簡(jiǎn)單,只是在使用方面可能會(huì)有點(diǎn)摸不著方向,它主要解決復(fù)雜的對(duì)象創(chuàng)建,比如參數(shù)過(guò)長(zhǎng)、校驗(yàn)過(guò)多等等。
為什么要使用建造者模式
我們都知道,創(chuàng)建對(duì)象的方法有很多,new是我們最常見(jiàn)也是最熟悉的一種,我們?yōu)槭裁床皇褂梦覀冏钍煜さ亩x用建造者模式呢?雖然new是我們最熟悉的,但不一定是最合適的,為什么這么說(shuō)呢?我們舉個(gè)例子來(lái)說(shuō)明一下。
我們現(xiàn)在定義一個(gè)對(duì)象:ThreadConfig,ThreadConfig有5個(gè)屬性:核心線(xiàn)程數(shù)(corePoolSize)、最大線(xiàn)程數(shù)(maxPoolSize)、隊(duì)列數(shù)(queueCapacity)、空閑時(shí)間退出(keepAliveTime)、是否允許線(xiàn)程退出(allowCoreThreadTimeout)。屬性有必填、有選填。
屬性名必填默認(rèn)值注釋threadName是
線(xiàn)程名corePoolSize否4核心線(xiàn)程數(shù)maxPoolSize是
核心線(xiàn)程數(shù)queueCapacity是
最大線(xiàn)程數(shù)keepAliveTime是
當(dāng)線(xiàn)程空閑時(shí)間達(dá)到keepAliveTime,該線(xiàn)程會(huì)退出allowCoreThreadTimeout是
是否允許核心線(xiàn)程數(shù)空閑時(shí)退出
創(chuàng)建對(duì)象的時(shí)候要滿(mǎn)足以下要求:
1.最大線(xiàn)程數(shù)不傳,默認(rèn)為核心線(xiàn)程數(shù)的大小。
2.最大線(xiàn)程數(shù)不能小于核心線(xiàn)程數(shù)。
3.如果填寫(xiě)隊(duì)列數(shù),隊(duì)列書(shū)不能小于等于0。
4.如果填寫(xiě)keepAliveTime,不能小于等于0。
看到這樣的一個(gè)對(duì)象,如果是你,你會(huì)怎么設(shè)計(jì)他的對(duì)象創(chuàng)建呢?
構(gòu)造函數(shù)創(chuàng)建對(duì)象
大家想到的第一種創(chuàng)建方式可能就是構(gòu)造函數(shù),那我們先使用構(gòu)造函數(shù)實(shí)現(xiàn)一下這個(gè)對(duì)象的創(chuàng)建
package com.ymy.builder;import lombok.ToString; import org.springframework.util.StringUtils;@ToString public class ThreadConfig {/** * 核心線(xiàn)程默認(rèn)值 */private static final Integer CORE_POOL_SIZE = 4;private String threadName;/** * 核心線(xiàn)程數(shù) */private Integer corePoolSize = CORE_POOL_SIZE;/** * 最大線(xiàn)程數(shù) */private Integer maxPoolSize;/** * 隊(duì)列數(shù) */private Integer queueCapacity;/** * 當(dāng)線(xiàn)程空閑時(shí)間達(dá)到keepAliveTime,該線(xiàn)程會(huì)退出 */private Integer keepAliveTime;/** * 是否允許核心線(xiàn)程數(shù)空閑時(shí)退出 */private boolean allowCoreThreadTimeout;public ThreadConfig(String threadName,Integer corePoolSize,Integer maxPoolSize,Integer queueCapacity,Integer keepAliveTime) throws IllegalAccessException {if(StringUtils.isEmpty(threadName)){throw new IllegalAccessException("線(xiàn)程名不能為空!");}this.threadName = threadName;if(null != corePoolSize ){if( corePoolSize <= 0){throw new IllegalAccessException("核心線(xiàn)程數(shù)不能小于等于0!");}this.corePoolSize = corePoolSize;}if(null != maxPoolSize ){if(maxPoolSize < this.corePoolSize){throw new IllegalAccessException("最大線(xiàn)程數(shù)不能小于核心線(xiàn)程數(shù)!");}this.maxPoolSize = corePoolSize;}if(null != queueCapacity ){if( queueCapacity <= 0 ){throw new IllegalAccessException("隊(duì)列書(shū)不能小于等于0!");}this.queueCapacity = queueCapacity;}if(null != keepAliveTime ){if( keepAliveTime <= 0 ){throw new IllegalAccessException("空閑時(shí)間不能小于等于0!");}this.keepAliveTime = keepAliveTime;}} }@ToString注解是lombok依賴(lài)提供的
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency>創(chuàng)建對(duì)象
package com.ymy.builder;public class Test {public static void main(String[] args) throws IllegalAccessException {ThreadConfig config = new ThreadConfig("thread-1",5,2,5,10);System.out.println(config);} }輸出結(jié)果:
Exception in thread "main" java.lang.IllegalAccessException: 最大線(xiàn)程數(shù)不能小于核心線(xiàn)程數(shù)!at com.ymy.builder.ThreadConfig.<init>(ThreadConfig.java:56)at com.ymy.builder.Test.main(Test.java:6)我這里給出的核心線(xiàn)程數(shù):5,但是最大線(xiàn)程數(shù)給的2,所以會(huì)拋出最大線(xiàn)程數(shù)不能小于核心線(xiàn)程數(shù)!這種方式看著很完美,但有一點(diǎn)很不友好,當(dāng)參數(shù)過(guò)多的時(shí)候容易出錯(cuò),為什么這么說(shuō)呢?你仔細(xì)看這行代碼
ThreadConfig config = new ThreadConfig("thread-1",5,2,5,10);除了第一個(gè)參數(shù),其他參數(shù)都是int類(lèi)型,看著好像沒(méi)啥大毛病,這是因?yàn)槲业膮?shù)還不夠多,如果我這里有10個(gè)參數(shù)需要傳遞,并且都是int類(lèi)型,這時(shí)候就會(huì)存在一個(gè)問(wèn)題,參數(shù)很可能會(huì)被寫(xiě)錯(cuò),比如最大線(xiàn)程數(shù)寫(xiě)到了隊(duì)列數(shù)中,而且有時(shí)候還不會(huì)報(bào)錯(cuò),只有在項(xiàng)目運(yùn)行的時(shí)候才會(huì)出現(xiàn)某種讓人摸不著頭腦的bug,所以使用構(gòu)造函數(shù)創(chuàng)建對(duì)象的時(shí)候不太適合參數(shù)過(guò)長(zhǎng),不但容易出錯(cuò),而且讓接手代碼的人也頭痛,代碼可讀性比較差,當(dāng)然當(dāng)參數(shù)只有一兩個(gè)的時(shí)候,構(gòu)造函數(shù)的創(chuàng)建方式還是很不錯(cuò)的。
set方式構(gòu)建對(duì)象
既然構(gòu)造函數(shù)會(huì)導(dǎo)致參數(shù)錯(cuò)誤以及可讀性較差,那我們能不能使用構(gòu)造函數(shù)+set方法來(lái)創(chuàng)建對(duì)象呢?我們可以嘗試一下,由于只有線(xiàn)程名是必傳,所以構(gòu)造函數(shù)只給定線(xiàn)程名,其他屬性都通過(guò)set賦值,改造一下代碼。
package com.ymy.builder;import lombok.ToString; import org.springframework.util.StringUtils;@ToString public class ThreadConfig {/** * 核心線(xiàn)程默認(rèn)值 */private static final Integer CORE_POOL_SIZE = 4;private String threadName;/** * 核心線(xiàn)程數(shù) */private Integer corePoolSize = CORE_POOL_SIZE;/** * 最大線(xiàn)程數(shù) */private Integer maxPoolSize;/** * 隊(duì)列數(shù) */private Integer queueCapacity;/** * 當(dāng)線(xiàn)程空閑時(shí)間達(dá)到keepAliveTime,該線(xiàn)程會(huì)退出 */private Integer keepAliveTime;/** * 是否允許核心線(xiàn)程數(shù)空閑時(shí)退出 */private boolean allowCoreThreadTimeout;public ThreadConfig(String threadName) throws IllegalAccessException {if(StringUtils.isEmpty(threadName)){throw new IllegalAccessException("線(xiàn)程名不能為空!");}this.threadName = threadName;}public void setCorePoolSize(Integer corePoolSize) throws IllegalAccessException {if(null != corePoolSize ){if( corePoolSize <= 0){throw new IllegalAccessException("核心線(xiàn)程數(shù)不能小于等于0!");}this.corePoolSize = corePoolSize;}}public void setMaxPoolSize(Integer maxPoolSize) throws IllegalAccessException {if(null != maxPoolSize ){if(maxPoolSize < this.corePoolSize){throw new IllegalAccessException("最大線(xiàn)程數(shù)不能小于核心線(xiàn)程數(shù)!");}this.maxPoolSize = corePoolSize;}}public void setQueueCapacity(Integer queueCapacity) throws IllegalAccessException {if(null != queueCapacity ){if( queueCapacity <= 0 ){throw new IllegalAccessException("隊(duì)列書(shū)不能小于等于0!");}this.queueCapacity = queueCapacity;}}public void setKeepAliveTime(Integer keepAliveTime) throws IllegalAccessException {if(null != keepAliveTime ){if( keepAliveTime <= 0 ){throw new IllegalAccessException("空閑時(shí)間不能小于等于0!");}this.keepAliveTime = keepAliveTime;}}public void setAllowCoreThreadTimeout(boolean allowCoreThreadTimeout) {this.allowCoreThreadTimeout = allowCoreThreadTimeout;} }改造完ThreadConfig之后我們創(chuàng)建對(duì)象的方式也會(huì)發(fā)生細(xì)微的變化,由之前構(gòu)造函數(shù)傳遞一堆參數(shù)變成了一個(gè)參數(shù),加上了set方法,初始值由set給定。
package com.ymy.builder;public class Test {public static void main(String[] args) throws IllegalAccessException {ThreadConfig config = new ThreadConfig("thread-1");config.setCorePoolSize(5);config.setMaxPoolSize(10);config.setQueueCapacity(2);config.setKeepAliveTime(100);config.setAllowCoreThreadTimeout(false);System.out.println(config);} }這種對(duì)象的創(chuàng)建方式可以有效的防止賦值屬性錯(cuò)亂的問(wèn)題,因?yàn)榭瓷先ヒ荒苛巳?#xff0c;基本上不會(huì)出錯(cuò),代碼可讀性也很強(qiáng),完美的解決了將所有參數(shù)都放在構(gòu)造函數(shù)的缺陷,那為什么還會(huì)出現(xiàn)建造者模式呢?可以仔細(xì)想一下,set方法這么完美,建造者模式還有必要嗎?我覺(jué)得建造者模式的出現(xiàn)并不是偶然。
我們現(xiàn)在稍微修改一下需求:當(dāng)corePoolSize(核心線(xiàn)程數(shù))被賦值的時(shí)候,最大線(xiàn)程數(shù)也必須要賦值,這個(gè)時(shí)候你覺(jué)得set方法還能滿(mǎn)足嗎?我覺(jué)得應(yīng)該是滿(mǎn)足不了了吧,這是一種情況,還有一種情況set也是滿(mǎn)足不了的,那就是我希望對(duì)象初始化的時(shí)候一次性將所有的屬性都賦值,之后將不能被修改,這一點(diǎn)也是set做不到的,set方法就是提供給調(diào)用者的,所以調(diào)用者可以通過(guò)set隨時(shí)修改ThreadConfig的屬性,如果處理不當(dāng),可能會(huì)造成某種安全隱患,這個(gè)時(shí)候你可能又想到,把corePoolSize、maxPoolSize也放到構(gòu)造函數(shù)中不就解決了corePoolSize賦值的時(shí)候maxPoolSize也一定要賦值的要求嗎,確實(shí)是能解決這個(gè)問(wèn)題,如果像這樣的參數(shù)很多呢?然后又有可能出現(xiàn)參數(shù)傳錯(cuò)導(dǎo)致詭異bug,所這時(shí)候建造者模式就閃亮登場(chǎng)了。
java實(shí)現(xiàn)建造者模式
第一種實(shí)現(xiàn)方式
既然構(gòu)造函數(shù)和set方法無(wú)法滿(mǎn)足我們的需求,那自然會(huì)有滿(mǎn)足我們需求的新技術(shù)出現(xiàn),按照之前的需求,線(xiàn)程名必填、corePoolSize(核心線(xiàn)程數(shù))被賦值的時(shí)候,最大線(xiàn)程數(shù)也必須要賦值,我們一起使用建造模式來(lái)實(shí)現(xiàn)一下這個(gè)對(duì)象的創(chuàng)建。
package com.ymy.builder;import lombok.ToString; import org.springframework.util.StringUtils;@ToString public class ThreadConfig {/** * 核心線(xiàn)程默認(rèn)值 */private static final Integer CORE_POOL_SIZE = 4;/** * 線(xiàn)程名 */private String threadName;/** * 核心線(xiàn)程數(shù) */private Integer corePoolSize = CORE_POOL_SIZE;/** * 最大線(xiàn)程數(shù) */private Integer maxPoolSize;/** * 隊(duì)列數(shù) */private Integer queueCapacity;/** * 當(dāng)線(xiàn)程空閑時(shí)間達(dá)到keepAliveTime,該線(xiàn)程會(huì)退出 */private Integer keepAliveTime;/** * 是否允許核心線(xiàn)程數(shù)空閑時(shí)退出 */private boolean allowCoreThreadTimeout;private ThreadConfig(ThreadConfig.Builder builder) {this.threadName = builder.threadName;if(null != builder.corePoolSize){this.corePoolSize = builder.corePoolSize;}this.maxPoolSize = builder.maxPoolSize;this.queueCapacity = builder.queueCapacity;this.keepAliveTime = builder.keepAliveTime;this.allowCoreThreadTimeout = builder.allowCoreThreadTimeout;}public static class Builder {/** * 線(xiàn)程名 */private String threadName;/** * 核心線(xiàn)程數(shù) */private Integer corePoolSize ;/** * 最大線(xiàn)程數(shù) */private Integer maxPoolSize;/** * 隊(duì)列數(shù) */private Integer queueCapacity;/** * 當(dāng)線(xiàn)程空閑時(shí)間達(dá)到keepAliveTime,該線(xiàn)程會(huì)退出 */private Integer keepAliveTime;/** * 是否允許核心線(xiàn)程數(shù)空閑時(shí)退出 */private boolean allowCoreThreadTimeout;public ThreadConfig build() throws IllegalAccessException { // 校驗(yàn)邏輯放到這里來(lái)做,包括必填項(xiàng)校驗(yàn)、依賴(lài)關(guān)系校驗(yàn)、約束條件校驗(yàn)等if (StringUtils.isEmpty(threadName)) {throw new IllegalAccessException("線(xiàn)程名不能為空");}if(corePoolSize != null && maxPoolSize == null){throw new IllegalAccessException("最大線(xiàn)程數(shù)必傳");}return new ThreadConfig(this);}public ThreadConfig.Builder corePoolSize(int corePoolSize) {if (corePoolSize <= 0) {throw new IllegalArgumentException("核心線(xiàn)程數(shù)不能小于等于0");}this.corePoolSize = corePoolSize;return this;}public ThreadConfig.Builder threadName(String threadName) {this.threadName = threadName;return this;}public ThreadConfig.Builder maxPoolSize(int maxPoolSize) {if (maxPoolSize < this.corePoolSize) {throw new IllegalArgumentException("最大線(xiàn)程數(shù)不能小于核心線(xiàn)程數(shù)");}this.maxPoolSize = maxPoolSize;return this;}public ThreadConfig.Builder queueCapacity(int queueCapacity) {if (queueCapacity <= 0) {throw new IllegalArgumentException("隊(duì)列不能小于等于0");}this.queueCapacity = queueCapacity;return this;}public ThreadConfig.Builder keepAliveTime(int keepAliveTime) {if (keepAliveTime <= 0) {throw new IllegalArgumentException("保持空閑線(xiàn)程可用的時(shí)間不能小于等于0");}this.keepAliveTime = keepAliveTime;return this;}public ThreadConfig.Builder allowCoreThreadTimeout(boolean allowCoreThreadTimeout) {this.allowCoreThreadTimeout = allowCoreThreadTimeout;return this;}}}我們來(lái)測(cè)試,傳入核心線(xiàn)程數(shù)不傳最先線(xiàn)程數(shù)
package com.ymy.builder;public class Test {public static void main(String[] args) throws IllegalAccessException {ThreadConfig config = new ThreadConfig.Builder().threadName("hello").corePoolSize(3).keepAliveTime(100).queueCapacity(2).allowCoreThreadTimeout(true).build();System.out.println(config);} }打印結(jié)果
Exception in thread "main" java.lang.IllegalAccessException: 最大線(xiàn)程數(shù)必傳at com.ymy.builder.ThreadConfig$Builder.build(ThreadConfig.java:89)at com.ymy.builder.Test.main(Test.java:12)核心線(xiàn)程數(shù)不傳
ThreadConfig config = new ThreadConfig.Builder().threadName("hello")//.corePoolSize(3).keepAliveTime(100).queueCapacity(2).allowCoreThreadTimeout(true).build();System.out.println(config);結(jié)果
ThreadConfig(threadName=hello, corePoolSize=4, maxPoolSize=null, queueCapacity=2, keepAliveTime=100, allowCoreThreadTimeout=true)Process finished with exit code 0這就說(shuō)明已經(jīng)達(dá)到了我們的預(yù)期效果,并且賦值清晰,不容易出錯(cuò),代碼的可讀性也比較高,但是也有一點(diǎn)是不足的,那就是ThreadConfig類(lèi)中會(huì)出現(xiàn)冗余的數(shù)據(jù)Builder。
建造者模式的參數(shù)校驗(yàn)放在了build()方法中,這樣做法的好處在于build是集中的處理參數(shù)問(wèn)題,只有校驗(yàn)通過(guò)之后才會(huì)給ThreadConfig對(duì)象實(shí)例化,為了對(duì)象的安全性,我們可以將ThreadConfig的構(gòu)造函數(shù)設(shè)置成private,同時(shí)取消set方法,強(qiáng)制使用builder方式創(chuàng)建對(duì)象,這樣就大大的保證了對(duì)象的安全性。
第二種方式
上面那種方式看著是不是很爽,但是創(chuàng)建對(duì)象的時(shí)候還是需要new ThreadConfig.Builder(),我現(xiàn)在想直接ThreadConfig.Builder()就能創(chuàng)建對(duì)象,我不想看到new,能不能實(shí)現(xiàn)呢?相信java,他能,我們一起來(lái)改造一下代碼
package com.ymy.builder;import lombok.ToString; import org.springframework.util.StringUtils;@ToString public class ThreadConfig {/** * 核心線(xiàn)程默認(rèn)值 */private static final Integer CORE_POOL_SIZE = 4;/** * 線(xiàn)程名 */private String threadName;/** * 核心線(xiàn)程數(shù) */private Integer corePoolSize = CORE_POOL_SIZE;/** * 最大線(xiàn)程數(shù) */private Integer maxPoolSize;/** * 隊(duì)列數(shù) */private Integer queueCapacity;/** * 當(dāng)線(xiàn)程空閑時(shí)間達(dá)到keepAliveTime,該線(xiàn)程會(huì)退出 */private Integer keepAliveTime;/** * 是否允許核心線(xiàn)程數(shù)空閑時(shí)退出 */private boolean allowCoreThreadTimeout;private ThreadConfig(ThreadConfig.Builder builder) {this.threadName = builder.threadName;if(null != builder.corePoolSize){this.corePoolSize = builder.corePoolSize;}this.maxPoolSize = builder.maxPoolSize;this.queueCapacity = builder.queueCapacity;this.keepAliveTime = builder.keepAliveTime;this.allowCoreThreadTimeout = builder.allowCoreThreadTimeout;}/** * 使用靜態(tài)方法替代new * @return */public static Builder builder() {return new Builder();}public static class Builder {/** * 構(gòu)造函數(shù),可以不寫(xiě) */Builder(){}/** * 線(xiàn)程名 */private String threadName;/** * 核心線(xiàn)程數(shù) */private Integer corePoolSize ;/** * 最大線(xiàn)程數(shù) */private Integer maxPoolSize;/** * 隊(duì)列數(shù) */private Integer queueCapacity;/** * 當(dāng)線(xiàn)程空閑時(shí)間達(dá)到keepAliveTime,該線(xiàn)程會(huì)退出 */private Integer keepAliveTime;/** * 是否允許核心線(xiàn)程數(shù)空閑時(shí)退出 */private boolean allowCoreThreadTimeout;public ThreadConfig build() throws IllegalAccessException { // 校驗(yàn)邏輯放到這里來(lái)做,包括必填項(xiàng)校驗(yàn)、依賴(lài)關(guān)系校驗(yàn)、約束條件校驗(yàn)等if (StringUtils.isEmpty(threadName)) {throw new IllegalAccessException("線(xiàn)程名不能為空");}if(corePoolSize != null && maxPoolSize == null){throw new IllegalAccessException("最大線(xiàn)程數(shù)必傳");}return new ThreadConfig(this);}public ThreadConfig.Builder corePoolSize(int corePoolSize) {if (corePoolSize <= 0) {throw new IllegalArgumentException("核心線(xiàn)程數(shù)不能小于等于0");}this.corePoolSize = corePoolSize;return this;}public ThreadConfig.Builder threadName(String threadName) {this.threadName = threadName;return this;}public ThreadConfig.Builder maxPoolSize(int maxPoolSize) {if (maxPoolSize < this.corePoolSize) {throw new IllegalArgumentException("最大線(xiàn)程數(shù)不能小于核心線(xiàn)程數(shù)");}this.maxPoolSize = maxPoolSize;return this;}public ThreadConfig.Builder queueCapacity(int queueCapacity) {if (queueCapacity <= 0) {throw new IllegalArgumentException("隊(duì)列不能小于等于0");}this.queueCapacity = queueCapacity;return this;}public ThreadConfig.Builder keepAliveTime(int keepAliveTime) {if (keepAliveTime <= 0) {throw new IllegalArgumentException("保持空閑線(xiàn)程可用的時(shí)間不能小于等于0");}this.keepAliveTime = keepAliveTime;return this;}public ThreadConfig.Builder allowCoreThreadTimeout(boolean allowCoreThreadTimeout) {this.allowCoreThreadTimeout = allowCoreThreadTimeout;return this;}} }其實(shí)改動(dòng)很小僅僅只是加了一個(gè)static Builder builder(),使用靜態(tài)方法替代new對(duì)象,這樣我們創(chuàng)建對(duì)象的時(shí)候就不需要new了,請(qǐng)看創(chuàng)建對(duì)象代碼
ThreadConfig config =ThreadConfig.builder().threadName("hello")// .corePoolSize(3).keepAliveTime(100).queueCapacity(2).allowCoreThreadTimeout(true).build();System.out.println(config);是不是爽多了,看著真舒服,不過(guò)話(huà)說(shuō)回來(lái),你們看這種創(chuàng)建方式想不想lombok中給對(duì)象加了@Builder注解之后的創(chuàng)建方式?沒(méi)錯(cuò),就是一樣的,因?yàn)閘ombok中的@Builder就是建造者模式,只不過(guò)他的build并沒(méi)有我們這里的條件判斷,他是直接將屬性返回了。
建造者模式與構(gòu)造函數(shù)的對(duì)比
**構(gòu)造函數(shù):**適用于參數(shù)較少,邏輯簡(jiǎn)單的對(duì)象創(chuàng)建,對(duì)于參數(shù)過(guò)多的對(duì)象創(chuàng)建可能會(huì)造成參數(shù)錯(cuò)亂的問(wèn)題而導(dǎo)致詭異bug。
**建造者模式:**適用于參數(shù)較多,邏輯判斷較復(fù)雜的對(duì)象創(chuàng)建,可以讓代碼簡(jiǎn)潔明了,但是對(duì)象的代碼增加了,不但增加了很多冗余字段,所以有時(shí)候表面看起來(lái)光鮮亮麗,內(nèi)心卻是無(wú)比丑陋。
建造者模式與工廠模式的對(duì)比
對(duì)工廠模式還不太明白的朋友可以參考一下:工廠模式:你還在使用一堆的if/else創(chuàng)建對(duì)象嗎?
我們知道工廠模式主要是創(chuàng)建一個(gè)類(lèi)型多個(gè)實(shí)現(xiàn)的對(duì)象,比如發(fā)送短信驗(yàn)證碼的處理方式有很多種情況,每種情況的處理方式都不相同,還有就是創(chuàng)建對(duì)象的時(shí)候需要經(jīng)過(guò)很多的判斷,這種情況下我們就可以考慮使用工廠模式來(lái)創(chuàng)建對(duì)象。
如果對(duì)象的職責(zé)比較單一,沒(méi)有多層含義,僅僅只是創(chuàng)建條件復(fù)雜,參數(shù)過(guò)多等等,使用建造者模式創(chuàng)建對(duì)象是首選,雖然對(duì)象中含有冗余代碼,但是對(duì)象的創(chuàng)建真的很絲滑。
總結(jié)
如果一個(gè)類(lèi)中包含著大量的屬性,我們可以通過(guò)構(gòu)造函數(shù)+set方法來(lái)進(jìn)行對(duì)象創(chuàng)建,但對(duì)象如果包含一下幾點(diǎn)特性,那么我推薦使用建造者模式。
1.必填的字段很多,這樣會(huì)導(dǎo)致構(gòu)造函數(shù)參數(shù)過(guò)長(zhǎng)的問(wèn)題。
2.如果屬性與屬性之間關(guān)聯(lián)性很強(qiáng),比如設(shè)置了核心線(xiàn)程數(shù)就必須要設(shè)置最大線(xiàn)程數(shù),這種情況下set方法是無(wú)法做到校驗(yàn)的。
3.如果當(dāng)前對(duì)象比較重要,我們希望對(duì)象被創(chuàng)建之后就不能被修改,所以這時(shí)候set方法就會(huì)被屏蔽,如果利用構(gòu)造函數(shù),又會(huì)出現(xiàn)字段過(guò)多問(wèn)題。
當(dāng)然了,我們不能為了用設(shè)計(jì)模式而用設(shè)計(jì)模式,對(duì)象一共就兩個(gè)屬性,我們也給他弄成建造者模式,這就有點(diǎn)大材小用,適得其反,一定要結(jié)合的實(shí)際的項(xiàng)目需求,不能盲目使用。
?
總結(jié)
以上是生活随笔為你收集整理的activexobject对象不能创建_【设计模式】建造者模式:你创建对象的方式有它丝滑吗?...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: kaggle房价预测特征意思_R语言实战
- 下一篇: cefsharp 发送请求服务器_使用