學(xué)AI,好工作 就找北大青鳥
關(guān)注小青 聽課做題,輕松學(xué)習(xí)
周一至周日
4000-9696-28

大話設(shè)計(jì)模式之工廠模式

來源:北大青鳥總部 2023年02月16日 14:40

摘要: 無論是簡(jiǎn)單工廠模式,工廠方法模式,還是抽象工廠模式,他們都屬于工廠模式,雖然在形式有些區(qū)別,但是最終目的都是為了解耦。

在程序猿世界里,能夠?qū)懗鰞?yōu)雅、可擴(kuò)展、低耦合、甚至像詩一樣的代碼,是每個(gè)程序猿畢生的追求~

秉承這個(gè)人生的終極理想,猿小二入職一家新公司,開始慢慢熟悉公司的代碼,越來越覺得不對(duì)勁,這家公司的代碼寫的可真爛,各種耦合牽一發(fā)動(dòng)全身,完全不是面試時(shí)老板說的公司的代碼都像詩一樣優(yōu)雅,猿小二感覺自己上當(dāng)了!

沒辦法,猿小二只能硬著頭皮繼續(xù)了,不過猿小二轉(zhuǎn)念一想,代碼這么多問題,不就是給我表現(xiàn)的機(jī)會(huì)嗎?猿小二心中竊喜,思考著如何用設(shè)計(jì)模式來重構(gòu)現(xiàn)在的代碼,增加程序間的可擴(kuò)展性并降低程序間的耦合度,猿小二想到最近正在研究的工廠模式,于是猿小二開始了他的改造之旅......



經(jīng)過了一段時(shí)間的努力,猿小二終于完成了一部分代碼的改造;正當(dāng)他在對(duì)自己的成就自信滿滿的時(shí)候,一些同事突然過來說改造之后的代碼雖然感覺很優(yōu)雅(不明覺厲),但是他們卻看不懂,猿小二說,我來給大家講一下我的改造之旅吧,其實(shí)也不是那么順利的,于是猿小二又開始了他的分享之旅~~~


簡(jiǎn)單工廠模式(靜態(tài)工廠模式)

最開始的時(shí)候,猿小二對(duì)一些代碼的改造使用了簡(jiǎn)單工廠模式,簡(jiǎn)單工廠就是有一個(gè)工廠類,根據(jù)傳入的參數(shù)不同創(chuàng)建不同的對(duì)象實(shí)例;比如說,有個(gè)生產(chǎn)汽車的工廠(CarFactory),可以生產(chǎn)各種不同品牌的汽車(AudiCar、BWMCar、AMGCar)



定義一個(gè)汽車的接口

/**
* 汽車接口 */
public interface Car {
// 汽車會(huì)跑
public void run();
}


定義各種品牌的汽車類,實(shí)現(xiàn)汽車接口

/**
* 奧迪汽車類
*/
public class AudiCar implements Car {
public void run() {
System.out.println("奧迪汽車...");
}
}
/**
* 寶馬汽車類
*/
public class BWMCar implements Car {
public void run() {
System.out.println("寶馬汽車...");
}
}


對(duì)于這些不同品牌的汽車我們就可以提供一個(gè)工廠類,來根據(jù)不同的品牌參數(shù)去生產(chǎn)不同的汽車

/**
* 汽車工廠
*/public class CarFactory {


// 生產(chǎn)不同品牌的汽車
public Car produce(String bank) {
if ("AudiCar".equals(bank)) {
return new AudiCar();
} else if ("BWMCar".equals(bank)) {
return new BWMCar();
}
return null;
}
}


有了工廠對(duì)象了,接下來就可以生產(chǎn)汽車了

/**
* 測(cè)試生產(chǎn)汽車
*/
public class CarTest {
public static void main(String[] args) {
// 創(chuàng)建汽車工廠
CarFactory carFactory = new CarFactory();
// 生產(chǎn)奧迪汽車
Car audi = carFactory.produce("Audi");
audi.run();
// 生產(chǎn)寶馬汽車
Car bwm = carFactory.produce("BWM");
bwm.run();
}
}


這樣以來的話,我們就可以不用關(guān)心具體汽車對(duì)象的生產(chǎn)過程,只需要根據(jù)傳遞的參數(shù)(汽車品牌)就可以創(chuàng)建需要的汽車品牌了。

不過還有一個(gè)問題,就是如果我們要生產(chǎn)其他品牌的汽車,比如:豐田汽車,就的去改工廠類CarFactory里代碼,如果是汽車品牌多了話,豈不是要經(jīng)常修改,這種頻繁修改的代碼的行為,這顯然不符合開放-封閉原則,對(duì)于追求極致的猿小二來說,顯然是接受不了的,于是他有開始新一輪的改造。


工廠方法模式

這個(gè)時(shí)候,猿小二想到了工廠方法模式,不同于簡(jiǎn)單工廠模式的是,工廠方法模式?jīng)]有使用統(tǒng)一的工廠去生產(chǎn)不同的汽車品牌,而是分別給不同的汽車品牌建設(shè)不同工廠,比如:要生產(chǎn)Audi汽車,就創(chuàng)建Audi的汽車工廠;這樣每一個(gè)汽車品牌都有自己獨(dú)立的汽車生產(chǎn)工廠。



首先,先抽取一個(gè)最頂層的汽車工廠接口

/**
* 汽車工廠
*/
public interface CarFactory {
// 生產(chǎn)汽車
public Car produce();
}


然后,讓不同的汽車品牌工廠都實(shí)現(xiàn)這個(gè)接口,比如:奧迪汽車工廠、寶馬汽車工廠、豐田汽車工廠。

/**
* 奧迪汽車工廠
*/
public class AudiCarFactory implements CarFactory {
// 負(fù)責(zé)生產(chǎn)奧迪汽車
public Car produce() {
return new AudiCar();
}
}


豐田汽車工廠

/**
* 豐田汽車廠
*/
public class TOYOTACarFactory implements CarFactory {
// 負(fù)責(zé)生產(chǎn)豐田汽車
public Car produce() {
return new TOYOTACar();
}
}


測(cè)試生產(chǎn)汽車

/**
* 汽車工廠方法測(cè)試
*/
public class CarFactoryMethodTest {
public static void main(String[] args) {
// 奧迪汽車廠生產(chǎn)奧迪汽車
CarFactory audiCarFactory = new AudiCarFactory();
Car audi = audiCarFactory.produce();
audi.run();
// 寶馬汽車廠生產(chǎn)寶馬汽車
CarFactory toyotaCarFactory = new TOYOTACarFactory();
Car toyota = toyotaCarFactory.produce();
toyota.run();
}
}


通過這種工廠方法模式,我們?cè)僖膊挥脫?dān)心增加汽車品牌而去修改汽車工廠的代碼了,只需要?jiǎng)?chuàng)建相應(yīng)品牌的汽車工廠類就可以了,而且這種方式還符合了設(shè)計(jì)模式的開放-封閉原則,簡(jiǎn)直是完美;雖然有可能隨著汽車品牌的增加,工廠類也不斷增加,一定程度上會(huì)增加系統(tǒng)的復(fù)雜度,但是相對(duì)于它帶來的好處還是可以接受的。

本來事情已經(jīng)告一段落,猿小二可以稍微輕松下了,沒想到老板說又有新的需求了,這些汽車廠要涉足汽車發(fā)動(dòng)機(jī)領(lǐng)域,想要自己生產(chǎn)汽車發(fā)動(dòng)機(jī),這可難壞了猿小二,本來按照原來的思路,可以在創(chuàng)建發(fā)動(dòng)機(jī)的工廠類,但是考慮到制造成本(發(fā)動(dòng)機(jī)和組裝在同一個(gè)工廠生產(chǎn)),準(zhǔn)備對(duì)原來的汽車工廠進(jìn)行改造。


抽象工廠模式

為了滿足新的需求,需要在對(duì)原來的工廠進(jìn)行改造,增加生產(chǎn)發(fā)動(dòng)機(jī)的方法,這種方式就涉及到另外一種抽象工廠模式,在抽象工廠模式中,每一個(gè)具體工廠都提供了多個(gè)工廠方法用于產(chǎn)生多種不同類型的對(duì)象,比如,汽車工廠既生產(chǎn)汽車,也生產(chǎn)汽車發(fā)動(dòng)機(jī),于是猿小二開始新一輪的改造。



首先,我們先定義抽象工廠類,它既可以生產(chǎn)汽車,也可以生產(chǎn)汽車發(fā)動(dòng)機(jī)

/**
* 抽象工廠
*/
public interface CarAbstractFactory {
// 生產(chǎn)汽車
public Car produce();


// 生產(chǎn)發(fā)動(dòng)機(jī)
public Engine createEngine();
}


奧迪汽車工廠類實(shí)現(xiàn)這個(gè)抽象接口,生產(chǎn)奧迪汽車和奧迪的發(fā)動(dòng)機(jī)

/**
* 奧迪汽車工廠
*/
public class AudiCarFactory implements CarAbstractFactory {
// 負(fù)責(zé)生產(chǎn)奧迪汽車
public Car produce() {
return new AudiCar();
}
// 生產(chǎn)奧迪發(fā)動(dòng)機(jī)
public Engine create() {
return new AudiEngie();
}
}


這樣我們就可以看到奧迪汽車廠就可以生產(chǎn)自己品牌的汽車和發(fā)動(dòng)機(jī),其他品牌也可以生產(chǎn)各自的汽車和發(fā)動(dòng)機(jī)

/**
* 抽象工廠測(cè)試
*/
public class AbstractFactoryTest {
public static void main(String[] args) {
// 奧迪汽車廠
CarAbstractFactory audiCarFactory = new AudiCarFactory();
// 生產(chǎn)奧迪汽車
Car produce = audiCarFactory.produce();
produce.run();
// 生產(chǎn)奧迪汽車發(fā)動(dòng)機(jī)
Engine audiengine = audiCarFactory.createEngine();
audiengine.createEngine();
}
}


從這里我們可以看出其實(shí)抽象工廠模式是一個(gè)工廠可以生產(chǎn)多個(gè)產(chǎn)品類,也就是一系列相互關(guān)聯(lián)的產(chǎn)品,比如:汽車和發(fā)動(dòng)機(jī)。

其實(shí),無論是簡(jiǎn)單工廠模式,工廠方法模式,還是抽象工廠模式,他們都屬于工廠模式,雖然在形式有些區(qū)別,但是最終目的都是為了解耦。在使用時(shí),我們不必去在意這個(gè)模式到底工廠方法模式還是抽象工廠模式,因?yàn)橥ǔG闆r下是結(jié)合使用;經(jīng)常你會(huì)發(fā)現(xiàn),明明使用的工廠方法模式,當(dāng)新需求來臨,稍加修改,加入了一個(gè)新方法后,由于類中的產(chǎn)品構(gòu)成了不同等級(jí)結(jié)構(gòu)中的產(chǎn)品族,它就變成抽象工廠模式了;而對(duì)于抽象工廠模式,當(dāng)減少一個(gè)方法使的提供的產(chǎn)品不再構(gòu)成產(chǎn)品族之后,它就演變成了工廠方法模式;所以,在使用工廠模式時(shí),只需要關(guān)心是不是達(dá)到我們的業(yè)務(wù)需求,并且最大限度降低系統(tǒng)間的耦合度。


標(biāo)簽: 工廠模式
熱門班型時(shí)間
人工智能就業(yè)班 即將爆滿
AI應(yīng)用線上班 即將爆滿
UI設(shè)計(jì)全能班 即將爆滿
數(shù)據(jù)分析綜合班 即將爆滿
軟件開發(fā)全能班 爆滿開班
網(wǎng)絡(luò)安全運(yùn)營班 爆滿開班
報(bào)名優(yōu)惠
免費(fèi)試聽
課程資料
官方微信
返回頂部
培訓(xùn)課程 熱門話題 站內(nèi)鏈接