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)師必備的知識體系。
