您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關(guān)靜態(tài)工廠方法怎么在Java項(xiàng)目中實(shí)現(xiàn),可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。
什么是靜態(tài)工廠方法
對(duì)于類而言,為了讓使用者獲取它自身的一個(gè)實(shí)例,最常用的方法就是提供一個(gè)公有的構(gòu)造器。
當(dāng)然,這里要介紹的是另一種方法——靜態(tài)工廠方法,一個(gè)返回類的實(shí)例的靜態(tài)方法。
舉個(gè)例子,Boolean的一個(gè)將基本類型boolean轉(zhuǎn)為封裝類的方法,valueOf:
public static Boolean valueOf(boolean b) { return (b ? TRUE : FALSE); }
為什么要使用靜態(tài)工廠方法
那么,我們?yōu)槭裁匆褂渺o態(tài)工廠方法,而不是使用構(gòu)造器呢?
因?yàn)殪o態(tài)工廠方法,具有以下三個(gè)特點(diǎn)——具名、環(huán)保、多子,下面一個(gè)個(gè)來講。
> 具名 靜態(tài)工廠方法有名稱
對(duì)于構(gòu)造器來說,根據(jù)入?yún)⒌牟煌梢杂卸鄠€(gè)構(gòu)造器,但是這些構(gòu)造器的名稱都是一樣的,使用者在調(diào)用時(shí)就會(huì)一頭霧水,到底應(yīng)該調(diào)用哪一個(gè)呢。
而使用了靜態(tài)工廠方法之后,你可以根據(jù)方法的功能給方法起不同的名字,只有名字起得好,使用者看到方法名就知道是什么意思,知道這時(shí)候應(yīng)該調(diào)用哪一個(gè)方法,大大提高了代碼的可讀性。
> 環(huán)保 不必每次調(diào)用的時(shí)候都創(chuàng)建一個(gè)新對(duì)象
使用構(gòu)造器,每次都會(huì)產(chǎn)生一個(gè)新的對(duì)象。
而靜態(tài)工廠方法,可以重復(fù)地返回預(yù)先創(chuàng)建好的對(duì)象。
上面Boolean就是一個(gè)非常好的例子,TRUE和FALSE兩個(gè)變量都是預(yù)先創(chuàng)建好的,而且都是不可變的final對(duì)象,誰需要用到了,就給它返回過去,也不用擔(dān)心被修改了。
下面就是TRUE和FALSE兩個(gè)變量的初始化代碼:
public final class Boolean implements java.io.Serializable, Comparable<Boolean> { /** * The {@code Boolean} object corresponding to the primitive * value {@code true}. */ public static final Boolean TRUE = new Boolean(true); /** * The {@code Boolean} object corresponding to the primitive * value {@code false}. */ public static final Boolean FALSE = new Boolean(false); ... }
> 多子 可以返回原返回類型的任何子類型的對(duì)象
使用構(gòu)造器,你只能返回一種類型的對(duì)象;而使用靜態(tài)工廠方法,你可以根據(jù)需要,返回原返回類型的任何子類型的對(duì)象。
以EnumSet的noneof方法為例:
/** * Creates an empty enum set with the specified element type. * * @param elementType the class object of the element type for this enum * set * @throws NullPointerException if <tt>elementType</tt> is null */ public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) { Enum[] universe = getUniverse(elementType); if (universe == null) throw new ClassCastException(elementType + " not an enum"); if (universe.length <= 64) return new RegularEnumSet<>(elementType, universe); else return new JumboEnumSet<>(elementType, universe); }
這個(gè)方法,出于性能的考慮,具體返回什么類型,由枚舉類型的數(shù)量決定,超過64,則返回JumboEnumSet,否則返回RegularEnumSet,而這兩種類對(duì)于使用者來說是不可見的,使用者只需要知道他是EnumSet就好。
也正是因?yàn)殪o態(tài)工廠方法有著比構(gòu)造器更大的優(yōu)勢(shì),我們?cè)趧?chuàng)建類時(shí),切忌第一反應(yīng)就是提供公有構(gòu)造器,要優(yōu)先考慮靜態(tài)工廠方法。
常見的靜態(tài)工廠方法名
這里附上靜態(tài)工廠方法的一些約定俗成的名稱:
valueOf/Of——類型轉(zhuǎn)換,返回的實(shí)例和入?yún)⒕哂邢嗤闹?,比如Boolean.valueOf()、EnumSet.valueOf()
getInstance——返回一個(gè)預(yù)先創(chuàng)建好的實(shí)例
newInstance——返回一個(gè)新的實(shí)例
靜態(tài)工廠方法難道不就是工廠模式嗎?
講到這里,可能會(huì)有很多人覺得這不就是工廠模式嗎?答:并不完全相同。
本文講的靜態(tài)工廠方法,和工廠模式一樣,都是用來取代構(gòu)造器的方法,都具有上面說的三個(gè)優(yōu)勢(shì):具名、環(huán)保、多子。
但是,兩者的實(shí)現(xiàn)方式和使用場(chǎng)景并不相同。
首先,直觀上看,在代碼結(jié)構(gòu)上,我們說的工廠模式,通常需要一個(gè)xxxFactory類,在里面定義工廠方法;而本文講的靜態(tài)工廠
方法,則只需要一個(gè)類,類本身就提供了生產(chǎn)對(duì)象的工廠方法。
其次,我們想一下,假如一個(gè)類,在設(shè)計(jì)的時(shí)候,就提供了靜態(tài)工廠方法,那么還需要使用工廠模式嗎?
是的,不需要。
也就是說,只有當(dāng)一個(gè)類沒有提供靜態(tài)工廠方法的時(shí)候,我們才需要使用工廠模式。
腦洞一下,假如蘋果公司有強(qiáng)大的零部件工廠,那它還需要富士康嗎?
總結(jié)
靜態(tài)工廠方法具有三大優(yōu)勢(shì)——具名、環(huán)保、多子。
如果一個(gè)類提供了靜態(tài)工廠方法,那么也就不需要考慮對(duì)這個(gè)類進(jìn)行工廠模式了。
我們?cè)趧?chuàng)建類時(shí),切忌第一反應(yīng)就是提供公有構(gòu)造器,要優(yōu)先考慮靜態(tài)工廠方法。
看完上述內(nèi)容,你們對(duì)靜態(tài)工廠方法怎么在Java項(xiàng)目中實(shí)現(xiàn)有進(jìn)一步的了解嗎?如果還想了解更多知識(shí)或者相關(guān)內(nèi)容,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝大家的支持。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。