設(shè)計模式之簡單工廠模式

Simple Factory Pattern:

Returns different instances based on different parameters.

簡單工廠模式:

??簡單工廠模式又稱為靜態(tài)工廠方法模式,它是一種類創(chuàng)建型模式。在簡單工廠模式中可以根據(jù)參數(shù)的不同返回不同類的實例。簡單工廠模式專門定義了一個類來負責創(chuàng)建其他類的實例,被創(chuàng)建的實例通常都具有共同的父類。

簡單工廠模式包含角色:

Factory(工廠角色)

工廠角色即工廠類,它是簡單工廠模式的核心,負責實現(xiàn)創(chuàng)建所有實例的內(nèi)部邏輯;在工廠類中提供了靜態(tài)的工廠方法factoryMethod(),它返回一個抽象產(chǎn)品類AbstractProduct,所有的具體產(chǎn)品都是抽象產(chǎn)品的子類。

Product(抽象產(chǎn)品角色)

??抽象產(chǎn)品角色是簡單工廠模式所創(chuàng)建的所有對象的父類,負責描述所有實例所共有的公共接口。

ConcretePrroduct(具體產(chǎn)品角色)

??具體產(chǎn)品角色是簡單工廠模式的創(chuàng)建目標,每一個具體產(chǎn)品角色都是抽象產(chǎn)品角色的子類,需要實現(xiàn)定義在抽象產(chǎn)品中的抽象方法。

下面給出簡單工廠模式實現(xiàn)代碼

抽象產(chǎn)品類(AbstractProduct)

??提供公共抽象方法

publicabstractclassAbstractProduct{

publicabstractvoiduse();

}

具體產(chǎn)品類(Plane)

??繼承抽象產(chǎn)品類,實現(xiàn)抽象方法

publicclassPlaneextendsAbstractProduct{

@Override

publicvoiduse(){

System.out.println("正在使用飛機");

}

}

具體產(chǎn)品類(Artillery)

??繼承抽象產(chǎn)品類,實現(xiàn)抽象方法

publicclassArtilleryextendsAbstractProduct{

@Override

publicvoiduse(){

System.out.println("正在使用大炮");

}

}

工廠類(Factory)

??根據(jù)參數(shù)返回實例

publicclassFactory{

publicstaticAbstractProductproduceProduct(String?product)throwsException{

if("plane".equalsIgnoreCase(product)){

System.out.println("生產(chǎn)飛機");

returnnewPlane();

}

elseif("artillery".equalsIgnoreCase(product)){

System.out.println("制造大炮");

returnnewArtillery();

}

else{

thrownewException("暫不能生產(chǎn)此產(chǎn)品!!!");

}

}

}

模式適用環(huán)境

工廠類負責創(chuàng)建的對象比較少。

客戶端只需要傳入?yún)?shù),對于如何創(chuàng)建對象不關(guān)心。

模式優(yōu)點

提供了專門的工廠類用于創(chuàng)建對象。

一定程度上提高了系統(tǒng)的靈活性。

模式缺點

工廠類負責所有產(chǎn)品的創(chuàng)建邏輯,一旦不能正常工作,整個系統(tǒng)都要受到影響。

會增加系統(tǒng)中類的個數(shù),一定程度上增加了系統(tǒng)的復雜度。

系統(tǒng)擴展困難,添加新產(chǎn)品就必須要修改工廠類的邏輯。

簡單工廠模式使用了靜態(tài)工廠方法,造成工廠角色無法形成基于繼承的等級結(jié)構(gòu)。

JDK源碼之簡單工廠模式

java.text.DateFormat

publicfinalstaticDateFormatgetTimeInstance()

{

returnget(DEFAULT,0,1,?Locale.getDefault(Locale.Category.FORMAT));

}

publicfinalstaticDateFormatgetTimeInstance(intstyle)

{

returnget(style,0,1,?Locale.getDefault(Locale.Category.FORMAT));

}

publicfinalstaticDateFormatgetTimeInstance(intstyle,

Locale?aLocale)

{

returnget(style,0,1,?aLocale);

}

publicfinalstaticDateFormatgetDateInstance()

{

returnget(0,?DEFAULT,2,?Locale.getDefault(Locale.Category.FORMAT));

}

publicfinalstaticDateFormatgetDateInstance(intstyle)

{

returnget(0,?style,2,?Locale.getDefault(Locale.Category.FORMAT));

}

publicfinalstaticDateFormatgetDateInstance(intstyle,

Locale?aLocale)

{

returnget(0,?style,2,?aLocale);

}

publicfinalstaticDateFormatgetDateTimeInstance()

{

returnget(DEFAULT,?DEFAULT,3,?Locale.getDefault(Locale.Category.FORMAT));

}

publicfinalstaticDateFormatgetDateTimeInstance(intdateStyle,

inttimeStyle)

{

returnget(timeStyle,?dateStyle,3,?Locale.getDefault(Locale.Category.FORMAT));

}

publicfinalstaticDateFormat

getDateTimeInstance(intdateStyle,inttimeStyle,?Locale?aLocale)

{

returnget(timeStyle,?dateStyle,3,?aLocale);

}

publicfinalstaticDateFormatgetInstance(){

returngetDateTimeInstance(SHORT,?SHORT);

}

這里的10個方法都是返回DateFormat,只是會根據(jù)傳入的參數(shù)不同,而返回不同的樣式。我們可以看到這些方法都調(diào)用了一個get()成員方法,下面我們來看看這個get()方法。

/**

*?Creates?a?DateFormat?with?the?given?time?and/or?date?style?in?the?given

*?locale.

*@paramtimeStyle?a?value?from?0?to?3?indicating?the?time?format,

*?ignored?if?flags?is?2

*@paramdateStyle?a?value?from?0?to?3?indicating?the?time?format,

*?ignored?if?flags?is?1

*@paramflags?either?1?for?a?time?format,?2?for?a?date?format,

*?or?3?for?a?date/time?format

*@paramloc?the?locale?for?the?format

*/

privatestaticDateFormatget(inttimeStyle,intdateStyle,

intflags,?Locale?loc){

/**

*?若flags=2,說明只返回帶日期的格式,那么10&01的結(jié)果就是0,不進入,

*?令timeStyle=-1,表示不返回時間格式。若flags為1或3的時候則進入,繼續(xù)判斷timeStyle是否合法。

*/

if((flags?&1)?!=0)?{

if(timeStyle?<0||?timeStyle?>3)?{

thrownewIllegalArgumentException("Illegal?time?style?"+?timeStyle);

}

}else{

timeStyle?=?-1;

}

/**

*?若flags=1,說明只返回帶日期的格式,那么01&10的結(jié)果就是0,不進入,

*?令dateStyle=-1,表示不返回日期格式。若flags為2或3的時候則進入,繼續(xù)判斷dateStyle是否合法。

*/

if((flags?&2)?!=0)?{

if(dateStyle?<0||?dateStyle?>3)?{

thrownewIllegalArgumentException("Illegal?date?style?"+?dateStyle);

}

}else{

dateStyle?=?-1;

}

LocaleProviderAdapter?adapter?=?LocaleProviderAdapter.getAdapter(DateFormatProvider.class,?loc);

DateFormat?dateFormat?=?get(adapter,?timeStyle,?dateStyle,?loc);

if(dateFormat?==null)?{

dateFormat?=?get(LocaleProviderAdapter.forJRE(),?timeStyle,?dateStyle,?loc);

}

returndateFormat;

}

注釋上已經(jīng)說得很明確了timeStyle代表時間的格式,值的范圍是0到3的整形。而dateStyle代表的是日期的格式,值的范圍也是0到3的整形。同時第三個參數(shù)flags是標記參數(shù),當參數(shù)是1的時候返回時間格式,當參數(shù)是2的時候返回日期格式,當參數(shù)是3的時候返回日期加時間的格式。而loc這個參數(shù),會根據(jù)你給定的對象,返回給定的顯示格式。通常每個國家或地區(qū)時間的展現(xiàn)方式也大不相同,而loc這個參數(shù)就是起到了這樣的作用,將格式轉(zhuǎn)換成指定國家或地區(qū)的格式。

在這里順便給大家推薦一個架構(gòu)交流群:617434785,里面會分享一些資深架構(gòu)師錄制的視頻錄像:有Spring,MyBatis,Netty源碼分析,高并發(fā)、高性能、分布式、微服務(wù)架構(gòu)的原理,JVM性能優(yōu)化這些成為架構(gòu)師必備的知識體系。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容