国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

詳解Java從工廠(chǎng)方法模式到 IOC/DI思想

瀏覽:84日期:2022-08-11 14:45:00
目錄前言工廠(chǎng)方法模式工廠(chǎng)方法的結(jié)構(gòu)工廠(chǎng)方法模式的樣例代碼工廠(chǎng)方法模式實(shí)現(xiàn)文件導(dǎo)出工廠(chǎng)方法與簡(jiǎn)單工廠(chǎng)的區(qū)別工廠(chǎng)方法模式的意義工廠(chǎng)方法模式與IOC、DI什么是IOC/DI?工廠(chǎng)方法與IOC/DI思想前言

簡(jiǎn)單工廠(chǎng)的本質(zhì)是選擇實(shí)現(xiàn),說(shuō)白了是由一個(gè)專(zhuān)門(mén)的類(lèi)去負(fù)責(zé)生產(chǎn)我們所需要的對(duì)象,從而將對(duì)象的創(chuàng)建從代碼中剝離出來(lái),實(shí)現(xiàn)松耦合。我們來(lái)看一個(gè)例子:

我們要?jiǎng)?chuàng)建一個(gè)文件導(dǎo)出工具

public interface FileOper{ public Boolean exceptFile(String data);}public class XMLFileOp implment FileOper{ public Boolean exceptFile(String data){ System.out.println('導(dǎo)出一個(gè)xml文件'); return true; } }public class Factory{ public static FileOper createFileOp(){return new XMLFileOp(); } }public Class Test{ public static void main(String args[]){ FileOper op = Factory.createFileOp(); op.exceptFile('測(cè)試');}}

這樣看起來(lái)沒(méi)什么問(wèn)題,那么我們既然做出來(lái)了這個(gè)結(jié)構(gòu),就是為了后續(xù)的擴(kuò)展它,例子中只是為了實(shí)現(xiàn)XML文件的導(dǎo)出,后續(xù),我們可以自己實(shí)現(xiàn)一個(gè)txt文件的導(dǎo)出類(lèi),只需要實(shí)現(xiàn)FileOper接口就好:

public Class TxtFileOp implment FileOper{ public Boolean ExceptFile(String data){ System.out.println('導(dǎo)出txt文件'); return true; } }

這時(shí)候我們還是通過(guò)工廠(chǎng)來(lái)獲取這個(gè)對(duì)象,只需將Factory中追加一個(gè)else if 即可通過(guò)傳參來(lái)獲取想要的對(duì)象了。

工廠(chǎng)方法模式

仔細(xì)分析上面的場(chǎng)景,事實(shí)上在實(shí)現(xiàn)導(dǎo)出文件的業(yè)務(wù)邏輯中,它根本不知道要使用哪一種導(dǎo)出文件的格式,因此這個(gè)對(duì)象根本就不應(yīng)該和具體導(dǎo)出文件的對(duì)象耦合在一起,它只需要面向?qū)С鑫募涌冢‵ileOper)就好,這是工廠(chǎng)的思想,我們上面用簡(jiǎn)單工廠(chǎng)沒(méi)錯(cuò)啊,但是后面又加入了新的擴(kuò)展

這樣一來(lái),又有新的問(wèn)題,面對(duì)新的類(lèi),簡(jiǎn)單工廠(chǎng)便不能提供動(dòng)態(tài)的擴(kuò)展,必須要去修改內(nèi)部的代碼,破壞了開(kāi)閉原則。我們上一篇也提到了,簡(jiǎn)單工廠(chǎng)也有它自身的缺陷,其中最嚴(yán)重的就是,它雖然對(duì)依賴(lài)對(duì)象的主體實(shí)現(xiàn)了解耦,可是它本身內(nèi)部卻耦合較為嚴(yán)重。這時(shí)候我們可以看看工廠(chǎng)方法模式了,工廠(chǎng)方法模式的思路很有意思:老子不管了!采取無(wú)為而治的方式。不是需要接口對(duì)象么,那就定義一個(gè)方法來(lái)創(chuàng)建,可是事實(shí)上它自己是不知道如何創(chuàng)建這個(gè)接口對(duì)象的,不過(guò)這不重要,定義成抽象方法就行了,交給子類(lèi)去實(shí)現(xiàn),老子欠債,兒子你來(lái)還。

工廠(chǎng)方法的結(jié)構(gòu)

詳解Java從工廠(chǎng)方法模式到 IOC/DI思想

Product:工廠(chǎng)方法所創(chuàng)建的具體對(duì)象的統(tǒng)一接口。

Factory:為該類(lèi)產(chǎn)品的抽象工廠(chǎng),其內(nèi)部有聲明的工廠(chǎng)方法,工廠(chǎng)方法多為抽象方法,且返回一個(gè)Product對(duì)象

ProductOne:為具體的產(chǎn)品,也就是Product的具體實(shí)現(xiàn)類(lèi),真正的工廠(chǎng)產(chǎn)物。

SpecificFactory:具體的工廠(chǎng),用于生產(chǎn)指定類(lèi)型的Product,例如圖中它只負(fù)責(zé)生產(chǎn) ProductOne這個(gè)對(duì)象。

工廠(chǎng)方法模式的樣例代碼

public class AbstractFactoryTest { public static void main(String[] args) {try { Product a; AbstractFactory af; af = (AbstractFactory) ReadXML1.getObject(); a = af.newProduct(); a.show();} catch (Exception e) { System.out.println(e.getMessage());} }}//抽象產(chǎn)品:提供了產(chǎn)品的接口interface Product { public void show();}//具體產(chǎn)品1:實(shí)現(xiàn)抽象產(chǎn)品中的抽象方法class ConcreteProduct1 implements Product { public void show() {System.out.println('具體產(chǎn)品1顯示...'); }}//具體產(chǎn)品2:實(shí)現(xiàn)抽象產(chǎn)品中的抽象方法class ConcreteProduct2 implements Product { public void show() {System.out.println('具體產(chǎn)品2顯示...'); }}//抽象工廠(chǎng):提供了廠(chǎng)品的生成方法interface AbstractFactory { public Product newProduct();}//具體工廠(chǎng)1:實(shí)現(xiàn)了廠(chǎng)品的生成方法class ConcreteFactory1 implements AbstractFactory { public Product newProduct() {System.out.println('具體工廠(chǎng)1生成-->具體產(chǎn)品1...');return new ConcreteProduct1(); }}//具體工廠(chǎng)2:實(shí)現(xiàn)了廠(chǎng)品的生成方法class ConcreteFactory2 implements AbstractFactory { public Product newProduct() {System.out.println('具體工廠(chǎng)2生成-->具體產(chǎn)品2...');return new ConcreteProduct2(); }}

基于XML解析的外部配置文件

class ReadXML1 { //該方法用于從XML配置文件中提取具體類(lèi)類(lèi)名,并返回一個(gè)實(shí)例對(duì)象 public static Object getObject() {try { //創(chuàng)建文檔對(duì)象 DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = dFactory.newDocumentBuilder(); Document doc; doc = builder.parse(new File('src/FactoryMethod/config1.xml')); //獲取包含類(lèi)名的文本節(jié)點(diǎn) NodeList nl = doc.getElementsByTagName('className'); Node classNode = nl.item(0).getFirstChild(); String cName = 'FactoryMethod.' + classNode.getNodeValue(); //System.out.println('新類(lèi)名:'+cName); //通過(guò)類(lèi)名生成實(shí)例對(duì)象并將其返回 Class<?> c = Class.forName(cName); Object obj = c.newInstance(); return obj;} catch (Exception e) { e.printStackTrace(); return null;} }}

上面是一個(gè)較為初級(jí)也較為經(jīng)典的工廠(chǎng)方法模板,工廠(chǎng)方法還有另一種用法,即抽象的工廠(chǎng)父類(lèi)除了創(chuàng)建對(duì)象的方法之外,還包含其他的一些方法,而工廠(chǎng)父類(lèi)通常使用這些方法來(lái)完成某些任務(wù),下面我們來(lái)看看這第二種表現(xiàn)方式。

工廠(chǎng)方法模式實(shí)現(xiàn)文件導(dǎo)出

根據(jù)上面工廠(chǎng)方法模式提供的思路,我們重新來(lái)思考并實(shí)現(xiàn)一下一開(kāi)始那個(gè)文件導(dǎo)出的功能。

/** * 文件導(dǎo)出接口 * 實(shí)現(xiàn)將指定數(shù)據(jù)的導(dǎo)出 * 擴(kuò)展:實(shí)現(xiàn)該接口,可指定生產(chǎn)具體文件類(lèi)型 * @author GCC */public interface ExportFileApi { /** * 導(dǎo)出文件 * @param data 待導(dǎo)出數(shù)據(jù) * @return boolean */ boolean exportFile(String data);}/** * 生產(chǎn)Excel文件導(dǎo)出器 * @author GCC */public class ExportExcelFile implements ExportFileApi { @Override public boolean exportFile(String data) {//todo 處理數(shù)據(jù)return false; }}/** * 導(dǎo)出功能口,工廠(chǎng) * @author GCC */public abstract class ExportFileOperate { public Logger logger = Logger.getLogger(ExportFileOperate.class); //使用產(chǎn)品對(duì)象來(lái)實(shí)現(xiàn)一定功能的方法,這里是實(shí)現(xiàn)數(shù)據(jù)導(dǎo)出 public void export(String data){ExportFileApi exportoper = methodFactory();if(exportoper.exportFile(data)){ logger.info('文件導(dǎo)出成功'); return;}logger.error('文件導(dǎo)出失敗'); } //工廠(chǎng)方法 protected abstract ExportFileApi;}/** * 將指定數(shù)據(jù)導(dǎo)出為Excel文件 * @author GCC */public class ExportExcelFileFactory extends ExportFileOperate { @Override protected ExportFileApi methodFactory() {return new ExportExcelFile(); }}/** * 客戶(hù)用例 */public class App { static Logger logger = Logger.getLogger(App.class); public static void main( String[] args ) {ExportFileOperate ex = new ExportExcelFileFactory();ex.export('測(cè)試數(shù)據(jù)'); }}

這里大家可能會(huì) 有疑惑,你這個(gè)實(shí)現(xiàn)方式怎么和前面提到的工廠(chǎng)方法模式的標(biāo)準(zhǔn)樣例不一樣? 其實(shí)這是工廠(chǎng)方法模式的另一種結(jié)構(gòu),確切地說(shuō)這才是真正意義上的工廠(chǎng)方法模式(上面的模板只是工廠(chǎng)方法的正常形態(tài))。

這一種的實(shí)現(xiàn)方式是 :父類(lèi)會(huì)是一個(gè)抽象類(lèi),里面包含創(chuàng)建所需對(duì)象的抽象方法(代碼樣例中ExportFileOperat類(lèi)的methodFactory()方法,這里ExportFileOperat類(lèi)就是所謂的工廠(chǎng)類(lèi),需要補(bǔ)充的是設(shè)計(jì)模型的使用,不要拘泥于命名名稱(chēng),可以根據(jù)實(shí)際需求來(lái)進(jìn)行相應(yīng)的變化),這些抽象方法就是工廠(chǎng)方法模式中的工廠(chǎng)方法。父類(lèi)里面,通常會(huì)有使用這些產(chǎn)品對(duì)象來(lái)實(shí)現(xiàn)一定的功能的方法(代碼樣例中ExportFileOperat類(lèi)的export()方法)。而這些方法所實(shí)現(xiàn)的功能通常都是公共功能,不管子類(lèi)選擇了何種具體的產(chǎn)品實(shí)現(xiàn),這些方法總能正常運(yùn)行。

之所以會(huì)有上面兩種方式,主要原因在于工廠(chǎng)方法對(duì)于客戶(hù)端的支持,這里需要弄清楚一個(gè)問(wèn)題,誰(shuí)在使用工廠(chǎng)方法所創(chuàng)建的對(duì)象?

事實(shí)上,在工廠(chǎng)方法模式里,應(yīng)該是工廠(chǎng)中的其他方法來(lái)使用工廠(chǎng)所創(chuàng)建的對(duì)象,為了方便,工廠(chǎng)方法創(chuàng)建的對(duì)象也可直接提供給外部的客戶(hù)端來(lái)調(diào)用,但工廠(chǎng)方法的本意是由Factory抽象父類(lèi)內(nèi)部的方法來(lái)使用工廠(chǎng)方法創(chuàng)建的對(duì)象。

以下這幅時(shí)序圖,即說(shuō)明了客戶(hù)端調(diào)用factory的兩種方式。

詳解Java從工廠(chǎng)方法模式到 IOC/DI思想

其實(shí)客戶(hù)端應(yīng)該使用Factory對(duì)象,或者是由Factory所創(chuàng)建出來(lái)的產(chǎn)品對(duì)象,對(duì)于客戶(hù)端使用Factory對(duì)象,這個(gè)時(shí)候工廠(chǎng)方法創(chuàng)建的對(duì)象,是Factory中的某些方法在用,對(duì)于使用那些由Factory創(chuàng)建出來(lái)的對(duì)象,這個(gè)時(shí)候工廠(chǎng)方法創(chuàng)建的對(duì)象,是構(gòu)成客戶(hù)端所需對(duì)象的一部分。

工廠(chǎng)方法與簡(jiǎn)單工廠(chǎng)的區(qū)別

下面我們看一個(gè)例子,這里我打算做個(gè)計(jì)算器,如果用簡(jiǎn)單工廠(chǎng)模式來(lái)做,它的結(jié)構(gòu)是這樣的:

詳解Java從工廠(chǎng)方法模式到 IOC/DI思想

public class SimpleFactory { public Calculator create(String type){switch (type){ case '+'://返回一個(gè)具有加法功能的計(jì)算器對(duì)象return new AddCalculator(); case '-'://返回一個(gè)具有減法功能的計(jì)算器對(duì)象return new DeCalculator(); default:return null;} }}

為了工廠(chǎng)更完整,采用傳參的靜態(tài)工廠(chǎng)方式來(lái)實(shí)現(xiàn),這樣我簡(jiǎn)單工廠(chǎng)里將通過(guò)Switch語(yǔ)句來(lái)管控生產(chǎn)哪一種計(jì)算類(lèi),這時(shí)候,突然來(lái)了新的需求,我需要一個(gè)乘法的功能,這時(shí)候我就得實(shí)現(xiàn)計(jì)算器接口,完成一個(gè)乘法類(lèi),同時(shí)去簡(jiǎn)單工廠(chǎng)的代碼里,追加一個(gè)case。

詳解Java從工廠(chǎng)方法模式到 IOC/DI思想

同理,我使用工廠(chǎng)方法的模式來(lái)做這個(gè)功能,這塊的類(lèi)圖則如上圖一樣,我的工廠(chǎng)代碼里不需要Switch了,只需要一個(gè)具有生產(chǎn)計(jì)算器對(duì)象的抽象方法的抽象工廠(chǎng)類(lèi)即可,當(dāng)我需要一個(gè)乘法能力的計(jì)算器時(shí),實(shí)現(xiàn)計(jì)算器接口,完成乘法類(lèi),然后繼承抽象工廠(chǎng),完成一個(gè)乘法的工廠(chǎng)子類(lèi),然后再用乘法的工廠(chǎng)子類(lèi)來(lái)創(chuàng)建乘法類(lèi)。然后再去修改客戶(hù)端。

上面一對(duì)比,嘿,這升級(jí)版的工廠(chǎng)方法怎么比簡(jiǎn)單工廠(chǎng)還復(fù)雜了!?肯定很多同學(xué)在看工廠(chǎng)設(shè)計(jì)模式的時(shí)候很困惑,簡(jiǎn)單工廠(chǎng)和工廠(chǎng)方法的區(qū)別在哪,明明感覺(jué)用簡(jiǎn)單工廠(chǎng)更方便呢?

其實(shí)回頭好好看看設(shè)計(jì)原則,就會(huì)發(fā)現(xiàn),這是一個(gè)解耦的過(guò)程,簡(jiǎn)單工廠(chǎng)模式最大的優(yōu)點(diǎn)在于工廠(chǎng)類(lèi)中包含了必要的邏輯判斷,根據(jù)客戶(hù)的選擇動(dòng)態(tài)的實(shí)例化相關(guān)的產(chǎn)品類(lèi),對(duì)于客戶(hù)端來(lái)說(shuō),除去了與具體產(chǎn)品對(duì)象的依賴(lài)。但問(wèn)題就是隨著你的新需求,如果使用簡(jiǎn)單工廠(chǎng),那么你就不得不去破壞開(kāi)閉原則,而看起來(lái)改動(dòng)更為復(fù)雜的工廠(chǎng)方法模式,你并不需要對(duì)以前的代碼進(jìn)行改動(dòng),只需要繼承,擴(kuò)展即可。仔細(xì)觀(guān)察一下,簡(jiǎn)單工廠(chǎng)是讓客戶(hù)端與依賴(lài)對(duì)象進(jìn)行解耦,而工廠(chǎng)方式模式又是對(duì)工廠(chǎng)的一層解耦,原本內(nèi)部耦合性較強(qiáng)的if else,變成了由客戶(hù)端或者配置文件來(lái)控制,工廠(chǎng)方法將簡(jiǎn)單工廠(chǎng)內(nèi)部的邏輯判斷移到了使用它的外部(客戶(hù)端或者配置文件)來(lái)控制。本來(lái)擴(kuò)展是需要修改工廠(chǎng)類(lèi)源代碼的,現(xiàn)在變成了客戶(hù)端修改調(diào)用或者配置文件中的一個(gè)參數(shù)。

工廠(chǎng)方法模式的意義

工廠(chǎng)方法模式的主要思想是讓父類(lèi)在不知情的情況下,完成自身功能的調(diào)用,而具體的實(shí)現(xiàn)則延遲到子類(lèi)來(lái)做;或者說(shuō)是在靜態(tài)工廠(chǎng)中,將其原本耦合的if else抽離出來(lái),配合配置文檔使用,將寫(xiě)死的if else靈活實(shí)現(xiàn)(配置文件并不是默認(rèn)必須要有的)。這樣在設(shè)計(jì)的時(shí)候,不用去考慮具體的實(shí)現(xiàn),需要某個(gè)對(duì)象,把它通過(guò)工廠(chǎng)方法返回就好,在使用這些對(duì)象實(shí)現(xiàn)功能的時(shí)候還是通過(guò)接口來(lái)操作,這里就有一點(diǎn)IOC的韻味了。

工廠(chǎng)方法模式與IOC、DI什么是IOC/DI?

想想之前沒(méi)有學(xué)習(xí)設(shè)計(jì)模式,剛學(xué)會(huì)使用Java就被Spring的bean配置文件支配的恐懼。

那時(shí)候你說(shuō)自己學(xué)Java,對(duì)方一定會(huì)問(wèn)你Spring,說(shuō)到Spring,肯定避不開(kāi)“什么是IOC,什么是DI?”這個(gè)讓人頭痛的問(wèn)題,那么,到底什么是IOC,DI?

看完工廠(chǎng)的設(shè)計(jì)思想,對(duì)這個(gè)問(wèn)題才開(kāi)始了真正的思考。

IOC——控制反轉(zhuǎn)

DI——依賴(lài)注入

除了上面脫口而出的回答,我想我們這些面向?qū)ο蟮某绦蛟硞儯瑧?yīng)該有個(gè)更深入的理解,到底什么是控制反轉(zhuǎn),什么是依賴(lài)注入。要想理解上面兩個(gè)概念,必須把問(wèn)題拆開(kāi)來(lái)看,先搞清楚基本的問(wèn)題幾個(gè)問(wèn)題:

主客體是誰(shuí),或者說(shuō)參與這個(gè)概念的都有誰(shuí)?

什么叫依賴(lài)?為什么會(huì)有依賴(lài)?

什么叫注入?注入的是什么?誰(shuí)注入誰(shuí)?

控制反轉(zhuǎn),誰(shuí)控制誰(shuí),控制的是什么,既然叫反轉(zhuǎn),正轉(zhuǎn)是啥?

下面我們一個(gè)個(gè)來(lái)解決問(wèn)題:

1、參與者,說(shuō)起參與者,一般我們?cè)谶@個(gè)概念中是有三個(gè)參與者,具體某個(gè)類(lèi),容器,某個(gè)對(duì)象所依賴(lài)的外部資源(另一個(gè)對(duì)象),就好比我有三個(gè)類(lèi),A,B,C,A對(duì)象我們把它想象成一個(gè)客戶(hù)端,B是它需要的一個(gè)外部的資源,C是一個(gè)叫容器的第三方。

2、什么叫依賴(lài),這個(gè)就比較好說(shuō)了,你有一個(gè)A類(lèi),但是你A類(lèi)的成員變量有一個(gè)是B類(lèi)的實(shí)例聲明,那么A就依賴(lài)于B,也就是說(shuō),A如果想正常運(yùn)轉(zhuǎn)(或者說(shuō)功能正常),必須得依賴(lài)于它的成員變量B,至于為什么會(huì)有依賴(lài),那也好理解了,面向?qū)ο缶褪菍⒐δ芊庋b,每個(gè)對(duì)象都功能單一,這樣有些復(fù)雜的對(duì)象需要實(shí)現(xiàn)復(fù)雜的功能,就必須需要其他類(lèi)的協(xié)同。

3、注入,就是說(shuō),A你的成員變量B只是聲明了一個(gè)變量,它對(duì)于對(duì)象A來(lái)說(shuō),只是一個(gè)引用,一個(gè)字符,本身并沒(méi)有實(shí)體,你可以new 一下這個(gè)變量的構(gòu)造函數(shù),才能使這個(gè)變量真正有靈魂,又或者用它來(lái)承接外部傳進(jìn)來(lái)的同類(lèi)實(shí)體,這里外部傳進(jìn)來(lái)B的方式就叫注入,注入的是這個(gè)變量類(lèi)型 具體的實(shí)例化對(duì)象。誰(shuí)來(lái)注入,當(dāng)然是容器C來(lái)注入給A,將B注入給A

4、簡(jiǎn)單來(lái)說(shuō)就是容器來(lái)控制A,控制的就是A所依賴(lài)的對(duì)象B實(shí)例的創(chuàng)建,反轉(zhuǎn)是與正轉(zhuǎn)對(duì)應(yīng)來(lái)說(shuō)的,什么是正轉(zhuǎn)呢,A類(lèi)中有個(gè)對(duì)象B的成員變量,正常情況下,A類(lèi)中功能用到B對(duì)象的時(shí)候,A要主動(dòng)去獲取一個(gè)B對(duì)象,例如new一下,這種情況被稱(chēng)為正向的。這樣就比較好理解反轉(zhuǎn)了,A不再去主動(dòng)獲取B對(duì)象了,而是被動(dòng)的等待B的到來(lái)(注入),等待容器C獲取一個(gè)B的實(shí)例,然后反向的注入進(jìn)A。

詳解Java從工廠(chǎng)方法模式到 IOC/DI思想

所以,綜上來(lái)看,控制反轉(zhuǎn)和依賴(lài)注入其實(shí)說(shuō)的是同一件事,說(shuō)白了就是對(duì)象創(chuàng)建這個(gè)責(zé)任歸誰(shuí)的問(wèn)題,依賴(lài)注入是從應(yīng)用程序的角度去描述,應(yīng)用程序依賴(lài)外部容器去創(chuàng)建并注入它所需要的外部資源對(duì)象。控制反轉(zhuǎn)是從容器的角度出發(fā),容器控制應(yīng)用程序,由容器反向地向應(yīng)用程序注入其所需要的外部對(duì)象。

其實(shí)IOC/DI并不是一種代碼實(shí)現(xiàn),更多的它是一種思想,它從思想上完成了 “主從換位” 的變化,應(yīng)用程序本來(lái)是主體,占絕對(duì)地位,它需要什么都會(huì)主動(dòng)出擊去獲取,過(guò)強(qiáng)的控制欲導(dǎo)致了它耦合過(guò)重,而在IOC/DI思想中,應(yīng)用程序變成被動(dòng)的等待容器的注入,需要啥只能提出來(lái),什么時(shí)候給,給什么樣子的,主動(dòng)權(quán)完全交給了容器,較強(qiáng)的實(shí)現(xiàn)了解耦,程序的靈活性也就高了

工廠(chǎng)方法與IOC/DI思想

從某個(gè)角度來(lái)看,工廠(chǎng)方法模式跟IOC/DI的思想很貼近。

上面也說(shuō)過(guò)了,IOC/DI就是讓?xiě)?yīng)用程序不再主動(dòng)獲取外部資源,而是被動(dòng)等待第三方的注入,那么在編寫(xiě)程序的時(shí)候,一旦遇到需要外部資源的地方,就會(huì)開(kāi)一個(gè)窗口,提供給容器一個(gè)注入的途徑,讓容器注入進(jìn)來(lái),細(xì)節(jié)這里就不過(guò)多贅述了,自己去找Spring聊吧。 下面用IOC/DI和工廠(chǎng)方法來(lái)實(shí)現(xiàn)一個(gè)樣例對(duì)比一下。

用IOC/DI來(lái)實(shí)現(xiàn)一個(gè)類(lèi)Person:

public class Person { private String name; //依賴(lài)文件操作對(duì)象 private FileUtil fileUtil; private int age; //提供set方法,供外部注入 public void setFileUtil(FileUtil fileUtil){this.fileUtil = fileUtil; }public void opFile(String fileurl){fileUtil.createFile(fileurl); } }

這就是IOC/DI思想來(lái)實(shí)現(xiàn)的一個(gè)類(lèi),我依賴(lài)FileUtil,沒(méi)事,我不管,我提供給你一個(gè)set的注入途徑,剩下的我不管了,我就默認(rèn)我用FileUtil的時(shí)候,它是真真切切存在在堆中的對(duì)象。(本質(zhì)是當(dāng)外部的容器,創(chuàng)建Person對(duì)象的時(shí)候,會(huì)發(fā)現(xiàn)它依賴(lài)FileUtil,然后容器去獲取一個(gè)FileUtil,通過(guò)Person提供的Set方法,將獲取的FileUtil對(duì)象注入進(jìn)去,然后一個(gè)完整的Person對(duì)象就被制造出來(lái)了,這個(gè)過(guò)程Person角度來(lái)看,Person是無(wú)感的)

下面用工廠(chǎng)方法來(lái)搞上面的例子:

public abstract class Person { private String name; private int age; //交給子類(lèi)去實(shí)現(xiàn)我的依賴(lài) public abstract FileUtil getFileutil(); public void opFile(String fileurl){getFileutil().createFile(fileurl); }}

這里,Person類(lèi)也是需要用到FileUtil,但是它也不需要主動(dòng)的去new一下FileUtil,而是通過(guò)抽象方法的形式,將FileUtil的實(shí)例化延申到子類(lèi)去實(shí)現(xiàn),其實(shí)就是變相地提供了一種注入渠道(標(biāo)準(zhǔn)bean中是通過(guò)set方法,容器調(diào)用Set方法注入需要的對(duì)象,而工廠(chǎng)方法則是通過(guò)實(shí)現(xiàn)子類(lèi),即讓子類(lèi)來(lái)完成依賴(lài)對(duì)象的注入)

仔細(xì)體會(huì)這兩種寫(xiě)法,對(duì)比他們的實(shí)現(xiàn),在思想層面來(lái)看,會(huì)發(fā)現(xiàn),工廠(chǎng)方法模式和IOC/DI的思想是相似的,都是“主動(dòng)變被動(dòng)”,“主位換從位”,從而獲得了更加靈活的程序結(jié)構(gòu)。

以上就是詳解Java從工廠(chǎng)方法模式到 IOC/DI思想的詳細(xì)內(nèi)容,更多關(guān)于Java從工廠(chǎng)方法模式到 IOC/DI思想的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: Java
相關(guān)文章:
主站蜘蛛池模板: 三级视频在线观看 | 免费国产一级特黄久久 | 九九九精品视频 | 在线观看一级毛片免费 | 成年午夜一级毛片视频 | 欧美一级大黄特黄毛片视频 | 国产精品天天爽夜夜欢张柏芝 | 日韩在线一区二区三区免费视频 | 日韩日b视频 | 欧美一区二区三区免费播放 | 亚洲一区二区免费看 | 欧美成人全部视频 | 久久久久国产成人精品亚洲午夜 | 国产一在线精品一区在线观看 | 一区二区三区欧美视频 | 久久欧美精品欧美久久欧美 | 久久免费视频网 | 久久最新 | 精品久久久久久久久中文字幕 | 色天天躁夜夜躁天干天干 | 欧美性色一级在线观看 | 久草视频福利在线观看 | 国产午夜精品理论片小yo奈 | 久久国产精品二区99 | 黄色毛片在线 | 久久99精品这里精品3 | 久久久久毛片成人精品 | 欧美曰韩一区二区三区 | 三级视频网站 | 国产精品免费久久久免费 | 国产在线精品一区二区不卡 | 亚洲天堂久久精品 | 久久免费高清 | 成人欧美一区二区三区黑人 | 精品99在线观看 | 黄网在线观看免费网站台湾swag | 国产免费自拍 | 精品综合 | 国产精品亚洲专一区二区三区 | 国产一区二区免费视频 | 亚洲特黄视频 |