Java設(shè)計模式——Factory工廠模式

針對Java設(shè)計模式淳玩,推薦一書《大話設(shè)計模式》:
鏈接: https://pan.baidu.com/s/16YZ8nMx6M2C94_dmMWjh0w 提取碼: aw5y

Factory工廠模式分為:

1)簡單工廠模式(Simple Factory) --- 普通工廠模式
2)工廠方法模式(Factory Method) --- 多工廠模式
3)抽象工廠模式(Abstract Factory) --- 抽象工廠模式

什么時候需要用工廠模式呢?

工廠非竿,從字面意思理解蜕着,就是造東西的地方。所以红柱,需要很多類型或者經(jīng)常升級換代承匣,就可以使用工廠模式。比如锤悄,寶馬工廠韧骗,它有很多產(chǎn)品,而且每一款產(chǎn)品還時不時地升個級零聚,換個代袍暴,所以就有工廠這個東西。
所以隶症,使用工廠模式政模,你需要確定一點:
工廠模式針對的是多態(tài)。也就是說蚂会,你的類型如果可能有很多派生淋样,使用工廠模式比較方便。
如果你的需求是經(jīng)常會添加的胁住,比如會添加某個方法趁猴,那么使用工廠模式反而很麻煩刊咳,因為你要修改一連串的項目文件

所以,工廠模式的適用場景大致有這些:
1)對象的創(chuàng)建過程(實例化)很復(fù)雜儡司,需要初始化很多參數(shù)芦缰,比如查詢數(shù)據(jù)庫等。
2)類本身有好多子類枫慷,這些類的創(chuàng)建過程在業(yè)務(wù)中容易發(fā)生改變让蕾,或者對類的調(diào)用容易發(fā)生改變。

工廠模式的優(yōu)點

1)解耦:把對象的創(chuàng)建和使用的過程分開
ClassA想調(diào)用ClassB(其實只是想調(diào)用B的方法)不再需要New一個B,B的實例化或听,就交給工廠類探孝。

2)統(tǒng)一管理對象的創(chuàng)建過程,降低代碼重復(fù)
如果很多地方都需要創(chuàng)建對象B(創(chuàng)建過程復(fù)雜)誉裆,那么很多地方都需要New B(),此時代碼重復(fù)就比較多顿颅。
如果把創(chuàng)建對象B的代碼放到工廠里統(tǒng)一管理,既減少了重復(fù)代碼足丢,也方便以后對B的創(chuàng)建過程的修改維護(hù)粱腻。

引子

中國有16億人,如果每人想買一輛寶馬斩跌,只需要告訴工廠绍些,你想買什么類型的寶馬,是寶馬320還是寶馬523……工廠直接生產(chǎn)出來給你就好了耀鸦,這就是通俗理解工廠模式柬批!通俗理解其好處就是:方便更改應(yīng)用程序和擴展。

工廠方法模式:
一個抽象產(chǎn)品類袖订,可以派生出多個具體產(chǎn)品類氮帐。
一個抽象工廠類,可以派生出多個具體工廠類洛姑。
每個具體工廠類只能創(chuàng)建一個具體產(chǎn)品類的實例上沐。

抽象工廠模式:
多個抽象產(chǎn)品類,每個抽象產(chǎn)品類可以派生出多個具體產(chǎn)品類楞艾。
一個抽象工廠類参咙,可以派生出多個具體工廠類。
每個具體工廠類可以創(chuàng)建多個具體產(chǎn)品類的實例产徊。

也有的人將簡單工廠模式看為工廠方法模式的一種特例昂勒,兩者歸為一類。所以實際分為兩類:工廠方法模式與抽象工廠模式舟铜,兩者區(qū)別如下:
(1)工廠方法模式只有一個抽象產(chǎn)品類,而抽象工廠模式有多個抽象產(chǎn)品類奠衔。
(2)工廠方法模式只有一個抽象工廠類谆刨,而抽象工廠模式有多個抽象工廠類塘娶。
(3)工廠方法模式的具體工廠類只能創(chuàng)建一個具體產(chǎn)品類的實例,而抽象工廠模式可以創(chuàng)建多個具體產(chǎn)品類的實例痊夭。

public class BMW320 {
    public BMW320(){
        System.out.println("制造-->BMW320");
    }
}
 
public class BMW523 {
    public BMW523(){
        System.out.println("制造-->BMW523");
    }
}
 
public class Customer {
    public static void main(String[] args) {
        BMW320 bmw320 = new BMW320();
        BMW523 bmw523 = new BMW523();
    }
}

這個例子刁岸,客戶必須要知道怎么去創(chuàng)建一款車才可以,這樣的話她我,客戶和車就緊密耦合在一起了虹曙。為了降低耦合,就出現(xiàn)了工廠類,把創(chuàng)建寶馬的操作細(xì)節(jié)都放到了工廠里面去,客戶直接使用工廠的創(chuàng)建工廠方法,傳入想要的寶馬車型號就行了,而不必去知道創(chuàng)建的細(xì)節(jié),這就是簡單工廠模式了番舆!
即我們建立一個工廠類方法來制造新的對象酝碳,如圖:


簡單工廠模式.jpg
//  產(chǎn)品類
abstract class BMW {
    public BMW(){
        
    }
}
 
public class BMW320 extends BMW {
    public BMW320() {
        System.out.println("制造-->BMW320");
    }
}
public class BMW523 extends BMW{
    public BMW523(){
        System.out.println("制造-->BMW523");
    }
}
// 工廠類
public class Factory {
    public BMW createBMW(int type) {
        switch (type) { 
        case 320:
            return new BMW320();
        case 523:
            return new BMW523();
        default:
            break;
        }
        return null;
    }
}
// 客戶類
public class Customer {
    public static void main(String[] args) {
        Factory factory = new Factory();
        BMW bmw320 = factory.createBMW(320);
        BMW bmw523 = factory.createBMW(523);
    }
}

簡單工廠模式又稱靜態(tài)工廠方法模式,它存在的目的很簡單:定義一個用于創(chuàng)建對象的接口恨狈。 先來看看它的組成:

  1. 工廠類角色:這是本模式的核心疏哗,含有一定的商業(yè)邏輯和判斷邏輯,用來創(chuàng)建產(chǎn)品
  2. 抽象產(chǎn)品角色:它一般是具體產(chǎn)品繼承的父類或者實現(xiàn)的接口
  3. 具體產(chǎn)品角色:工廠類所創(chuàng)建的對象就是此角色的實例禾怠。在java中由一個具體類實現(xiàn)返奉。
    好了,現(xiàn)在假若客戶想要增加車型吗氏,比如奔馳芽偏、保時捷……那么,就需要在工廠類中增加相應(yīng)的創(chuàng)建業(yè)務(wù)邏輯弦讽,如果需要增加大量車型哮针,那就得吐血了,所以坦袍,就出現(xiàn)了工廠方法模式 十厢。

------- 工廠方法模式 ---------
工廠方法模式去掉了簡單工廠模式中工廠方法的靜態(tài)屬性,使得它可以被子類繼承捂齐,這樣在簡單工廠模式里集中在工廠方法上的壓力可以由工廠方法模式里不同的工廠子類來分擔(dān)蛮放。
工廠方法模式組成:
1)抽象工廠角色: 這是工廠方法模式的核心,它與應(yīng)用程序無關(guān)奠宜。是具體工廠角色必須實現(xiàn)的接口或者必須繼承的父類包颁。在java中它由抽象類或者接口來實現(xiàn)。
2)具體工廠角色:它含有和具體業(yè)務(wù)邏輯有關(guān)的代碼压真。由應(yīng)用程序調(diào)用以創(chuàng)建對應(yīng)的具體產(chǎn)品的對象娩嚼。
3)抽象產(chǎn)品角色:它是具體產(chǎn)品繼承的父類或者是實現(xiàn)的接口。在java中一般有抽象類或者接口來實現(xiàn)滴肿。
4)具體產(chǎn)品角色:具體工廠角色所創(chuàng)建的對象就是此角色的實例岳悟。在java中由具體的類來實現(xiàn)。
看如下代碼:

// 產(chǎn)品類
abstract class BMW {
    public BMW(){
        
    }
}
public class BMW320 extends BMW {
    public BMW320() {
        System.out.println("制造-->BMW320");
    }
}
public class BMW523 extends BMW{
    public BMW523(){
        System.out.println("制造-->BMW523");
    }
}
// 工廠類
interface FactoryBMW {
    BMW createBMW();
}
 
public class FactoryBMW320 implements FactoryBMW{
    @Override
    public BMW320 createBMW() {
        return new BMW320();
    }
}

public class FactoryBMW523 implements FactoryBMW {
    @Override
    public BMW523 createBMW() {
        return new BMW523();
    }
}
// 客戶類
public class Customer {
    public static void main(String[] args) {
        FactoryBMW320 factoryBMW320 = new FactoryBMW320();
        BMW320 bmw320 = factoryBMW320.createBMW();
 
        FactoryBMW523 factoryBMW523 = new FactoryBMW523();
        BMW523 bmw523 = factoryBMW523.createBMW();
    }
}

工廠方法模式仿佛已經(jīng)很完美的對對象的創(chuàng)建進(jìn)行了包裝,使得客戶程序中僅僅處理抽象產(chǎn)品角色提供的接口贵少,但這樣會使得對象的數(shù)量成倍增長呵俏。當(dāng)產(chǎn)品種類非常多時,會出現(xiàn)大量的與之對應(yīng)的工廠對象滔灶,所以就出現(xiàn)抽象工廠模式了普碎。

---------- 抽象工廠模式 ---------
隨著客戶的要求越來越高,寶馬車需要不同配置的空調(diào)和發(fā)動機等配件录平。于是這個工廠開始生產(chǎn)空調(diào)和發(fā)動機麻车,用來組裝汽車。這時候工廠有兩個系列的產(chǎn)品:空調(diào)和發(fā)動機斗这。寶馬320系列配置A型號空調(diào)和A型號發(fā)動機动猬,寶馬230系列配置B型號空調(diào)和B型號發(fā)動機。
抽象工廠模式是工廠方法模式的升級版本涝影,他用來創(chuàng)建一組相關(guān)或者相互依賴的對象枣察,代碼:

// 產(chǎn)品類
//發(fā)動機以及型號  
public interface Engine {  
 
}  
public class EngineA extends Engine{  
    public EngineA(){  
        System.out.println("制造-->EngineA");  
    }  
}  
public class EngineBextends Engine{  
    public EngineB(){  
        System.out.println("制造-->EngineB");  
    }  
}  
//空調(diào)以及型號  
public interface Aircondition {  
 
}  
public class AirconditionA extends Aircondition{  
    public AirconditionA(){  
        System.out.println("制造-->AirconditionA");  
    }  
}  
public class AirconditionB extends Aircondition{  
    public AirconditionB(){  
        System.out.println("制造-->AirconditionB");  
    }  
}
// 工廠類
//創(chuàng)建工廠的接口  
public interface AbstractFactory {  
    //制造發(fā)動機
    public Engine createEngine();
    //制造空調(diào) 
    public Aircondition createAircondition(); 
}  
//為寶馬320系列生產(chǎn)配件  
public class FactoryBMW320 implements AbstractFactory{   
    @Override  
    public Engine createEngine() {    
        return new EngineA();  
    }  
    @Override  
    public Aircondition createAircondition() {  
        return new AirconditionA();  
    }  
}  
//寶馬523系列
public class FactoryBMW523 implements AbstractFactory {  
     @Override  
    public Engine createEngine() {    
        return new EngineB();  
    }  
    @Override  
    public Aircondition createAircondition() {  
        return new AirconditionB();  
    }  
} 
// 客戶類
public class Customer {  
    public static void main(String[] args){  
        //生產(chǎn)寶馬320系列配件
        FactoryBMW320 factoryBMW320 = new FactoryBMW320();  
        factoryBMW320.createEngine();
        factoryBMW320.createAircondition();
          
        //生產(chǎn)寶馬523系列配件  
        FactoryBMW523 factoryBMW523 = new FactoryBMW523();  
        factoryBMW320.createEngine();
        factoryBMW320.createAircondition();
    }  
}

抽象工廠模式和工廠方法模式的區(qū)別,仔細(xì)看代碼就能體會燃逻。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末序目,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子伯襟,更是在濱河造成了極大的恐慌猿涨,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件姆怪,死亡現(xiàn)場離奇詭異叛赚,居然都是意外死亡,警方通過查閱死者的電腦和手機稽揭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進(jìn)店門俺附,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人溪掀,你說我怎么就攤上這事事镣。” “怎么了揪胃?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵璃哟,是天一觀的道長。 經(jīng)常有香客問我喊递,道長随闪,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任骚勘,我火速辦了婚禮铐伴,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己盛杰,他們只是感情好挽荡,可當(dāng)我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布藐石。 她就那樣靜靜地躺著即供,像睡著了一般。 火紅的嫁衣襯著肌膚如雪于微。 梳的紋絲不亂的頭發(fā)上逗嫡,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天,我揣著相機與錄音株依,去河邊找鬼驱证。 笑死,一個胖子當(dāng)著我的面吹牛恋腕,可吹牛的內(nèi)容都是我干的抹锄。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼荠藤,長吁一口氣:“原來是場噩夢啊……” “哼伙单!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起哈肖,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤吻育,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后淤井,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體布疼,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年币狠,在試婚紗的時候發(fā)現(xiàn)自己被綠了游两。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡漩绵,死狀恐怖贱案,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情渐行,我是刑警寧澤轰坊,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站祟印,受9級特大地震影響肴沫,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蕴忆,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一颤芬、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦站蝠、人聲如沸汰具。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽留荔。三九已至,卻和暖如春澜倦,著一層夾襖步出監(jiān)牢的瞬間聚蝶,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工藻治, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留碘勉,地道東北人。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓桩卵,卻偏偏與公主長得像验靡,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子雏节,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 參考資料:菜鳥教程之設(shè)計模式 設(shè)計模式概述 設(shè)計模式(Design pattern)代表了最佳的實踐胜嗓,通常被有經(jīng)驗...
    Steven1997閱讀 1,167評論 1 12
  • 設(shè)計模式匯總 一、基礎(chǔ)知識 1. 設(shè)計模式概述 定義:設(shè)計模式(Design Pattern)是一套被反復(fù)使用矾屯、多...
    MinoyJet閱讀 3,906評論 1 15
  • 一兼蕊、工廠模式介紹 工廠模式專門負(fù)責(zé)將大量有共同接口的類實例化。工廠模式可以動態(tài)決定將哪一個類實例化件蚕,不必事先知道每...
    QuantRuu閱讀 753評論 0 51
  • 果然沒基礎(chǔ)要多練習(xí)孙技,配色是個硬傷,~(>_<)~ 重新買的紙昨天剛到排作,交的晚了牵啦。請老師幫忙指導(dǎo)下,謝謝
    立夏凝音閱讀 237評論 2 0
  • 這幾天假期妄痪,全用在陪病人上了哈雏,覺得這幾天真的過得很快,今天終于冒著小雨衫生,騰出了時間收拾一下花盆裳瘪,又畫了這幾個小...
    哈皮翠鳥閱讀 1,311評論 0 2