工厂模式理解_工厂模式
工廠(chǎng)模式理解
工廠(chǎng)模式是一種創(chuàng)新的設(shè)計(jì)模式,其目的是提供一個(gè)接口,用于創(chuàng)建相關(guān)或相關(guān)對(duì)象的族,而無(wú)需指定其具體類(lèi)。 創(chuàng)建邏輯封裝在工廠(chǎng)中,該工廠(chǎng)提供創(chuàng)建邏輯的方法或?qū)?duì)象的創(chuàng)建委托給子類(lèi)。 客戶(hù)端不知道接口或類(lèi)的不同實(shí)現(xiàn)。 客戶(hù)端只需要知道工廠(chǎng)即可用于獲取接口實(shí)現(xiàn)之一的實(shí)例。 客戶(hù)端與對(duì)象的創(chuàng)建是分離的。
通常,工廠(chǎng)模式以單例或靜態(tài)類(lèi)的形式實(shí)現(xiàn),因?yàn)橹恍枰粋€(gè)工廠(chǎng)實(shí)例。 這樣集中了對(duì)象的創(chuàng)建。
CDI框架
在Java EE中,我們可以利用CDI框架來(lái)創(chuàng)建對(duì)象,而無(wú)需了解對(duì)象創(chuàng)建的詳細(xì)信息。 這種脫鉤是Java EE實(shí)現(xiàn)控制反轉(zhuǎn)的方式的結(jié)果。 傳達(dá)的最重要的好處是將較高級(jí)別的類(lèi)別與較低級(jí)別的類(lèi)別分離。 這種解耦使具體類(lèi)的實(shí)現(xiàn)可以更改而不會(huì)影響客戶(hù)端:減少耦合并提高靈活性。
CDI框架本身是工廠(chǎng)模式的實(shí)現(xiàn)。 容器在應(yīng)用程序啟動(dòng)期間創(chuàng)建合格對(duì)象,并將其注入到與注入標(biāo)準(zhǔn)匹配的任何注入點(diǎn)中。 客戶(hù)端不需要知道關(guān)于對(duì)象的具體實(shí)現(xiàn)的任何信息,甚至客戶(hù)端都不知道具體類(lèi)的名稱(chēng)。
public class CoffeeMachine implements DrinksMachine {// Implementation code}像這樣使用它:
@InjectDrinksMachine drinksMachine;在這里,容器創(chuàng)建了CoffeeMachine具體類(lèi)的實(shí)例,根據(jù)其接口DrinksMachine進(jìn)行選擇,并在容器找到合格注入點(diǎn)的任何位置進(jìn)行注入。 這是使用工廠(chǎng)模式的CDI實(shí)現(xiàn)的最簡(jiǎn)單方法。 但是,它不是最靈活的。
消歧
如果我們有多個(gè)DrinksMachine接口的具體實(shí)現(xiàn), 將會(huì)發(fā)生什么?
public class CoffeeMachine implements DrinksMachine {// Implementation code} public class SoftDrinksMachine implements DrinksMachine {// Implementation code}應(yīng)該注入哪種實(shí)現(xiàn)? SoftDrinksMachine或CoffeeMachine ?
@InjectDrinksMachine drinksMachine;容器不知道,因此部署將因“模棱兩可的依賴(lài)項(xiàng)”錯(cuò)誤而失敗。
資格賽
那么容器如何區(qū)分具體的實(shí)現(xiàn)? Java EE為我們提供了一個(gè)新工具:限定符。 限定詞是自定義注釋,用于標(biāo)記具體的類(lèi)以及容器要注入對(duì)象的位置。
回到我們的Drinks機(jī)器以及兩個(gè)相同類(lèi)型的CoffeeMachine和SoftDrinksMachine的具體類(lèi),我們將通過(guò)使用兩個(gè)限定符來(lái)區(qū)分它們:
@Qualifier@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.METHOD, ElementType.FIELD})public @interface SoftDrink@Qualifier@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.METHOD, ElementType.FIELD})public @interface Coffee我們創(chuàng)建一個(gè)限定符名稱(chēng)SoftDrink 。 這將注釋SoftDrinksMachine混凝土類(lèi),而Coffee將注釋CoffeeMachine類(lèi)。
@Target注釋限制了我們可以在哪里使用這些限定符標(biāo)記注入點(diǎn),在這種情況下,是在方法和字段注入點(diǎn)上。 具有保留策略RUNTIME的注釋可確保注釋在運(yùn)行時(shí)可用于JVM。
Target的可能值為:TYPE,METHOD,FIELD,PARAMETER。
正確標(biāo)注了DrinksMachine接口的兩個(gè)具體實(shí)現(xiàn)。 CoffeeMachine類(lèi)的注釋為@Coffee,而SoftDrinksMachine類(lèi)的注釋為@SoftDrink 。
@Coffeepublic class CoffeeMachine implements DrinksMachine {// Implementation code}@SoftDrinkpublic class SoftDrinksMachine implements DrinksMachine {// Implementation code}現(xiàn)在,您注釋注入點(diǎn)。 使用限定符@SoftDrink表示要在容器中注入SoftDrinksMachine類(lèi)的位置,并使用限定符@Coffee來(lái)在容器中注入CoffeeDrinkMachine的位置 。 現(xiàn)在,我們已經(jīng)向容器明確了應(yīng)該在哪里注入我們的具體實(shí)現(xiàn),并且部署將成功。
@Inject @SoftDrinkDrinksMachine softDrinksMachine;@Inject @CoffeeDrinksMachine coffeeDrinksMachine;我們已經(jīng)了解了Java EE的CDI框架如何實(shí)現(xiàn)工廠(chǎng)模式,如何隱藏對(duì)象的具體實(shí)現(xiàn)并允許創(chuàng)建與使用分離。 我們已經(jīng)看到了如何使用限定符來(lái)選擇所需的實(shí)現(xiàn),而無(wú)需了解有關(guān)對(duì)象創(chuàng)建的任何知識(shí)。
重要的是要記住,CDI框架只會(huì)實(shí)例化滿(mǎn)足托管Bean規(guī)范JSR 299的所有條件的POJO。但是,如果您要注入的對(duì)象沒(méi)有,那意味著我們不能利用CDI怎么辦?框架針對(duì)不符合要求的類(lèi)的注入功能。 不,不是。 Java EE為我們提供了一個(gè)解決方案。 讓我們更深入地研究一下如何使用CDI框架將ANY類(lèi)型的ANY類(lèi)注入到注入點(diǎn)中。
生產(chǎn)者方法
Java EE具有稱(chēng)為生產(chǎn)者方法的功能。 這些方法提供了一種實(shí)例化方式,因此可用于不符合托管bean規(guī)范的注入對(duì)象,例如需要使用構(gòu)造函數(shù)參數(shù)進(jìn)行正確實(shí)例化的對(duì)象。 其值可能會(huì)在運(yùn)行時(shí)更改的對(duì)象以及其創(chuàng)建需要進(jìn)行一些自定義初始化的對(duì)象,也可以通過(guò)生產(chǎn)者方法準(zhǔn)備好進(jìn)行注入。
讓我們看一個(gè)生產(chǎn)者方法,該方法產(chǎn)生一個(gè)用Books對(duì)象填充的List。
@Produces@Librarypublic List<Book> getLibrary(){// Generate a List of books called 'library'return library;}Book對(duì)象列表將被注入到注解點(diǎn)@Library中。
像這樣使用它:
@Inject @LibraryList<Books> library;生產(chǎn)者方法的一個(gè)重要特征是它的范圍。 這將確定何時(shí)調(diào)用該方法以及該方法產(chǎn)生的對(duì)象將保留多長(zhǎng)時(shí)間。
默認(rèn)情況下,生產(chǎn)者方法范圍是@DependentScoped 。 這意味著它將繼承其客戶(hù)范圍。
我們可以通過(guò)擴(kuò)大范圍來(lái)進(jìn)一步擴(kuò)展此示例。 如果我們對(duì)生產(chǎn)者方法@RequestScoped進(jìn)行注釋,則它將對(duì)其參與的每個(gè)HTTP請(qǐng)求僅調(diào)用一次,并持續(xù)到請(qǐng)求的持續(xù)時(shí)間。
@RequestScoped@Produces@Librarypublic List<Book> getLibrary(){// Generate a List of books called 'library'return library;}可能的范圍是:
- RequestScoped – HTTP請(qǐng)求范圍
- SessionScoped – HTTP會(huì)話(huà)范圍
- ApplicationScoped –在用戶(hù)之間共享
- ConversationScoped –與JSF的交互
- DependentScoped –默認(rèn),從客戶(hù)端繼承
優(yōu)點(diǎn):易于實(shí)現(xiàn),沒(méi)有樣板代碼,神奇地工作,任何對(duì)象都可以注入,按類(lèi)自動(dòng)配置
錯(cuò)誤:命名注釋類(lèi)型不安全
和丑陋:隱藏對(duì)象創(chuàng)建,難以遵循執(zhí)行流程,IDE應(yīng)該有所幫助
翻譯自: https://www.javacodegeeks.com/2015/12/factory-pattern.html
工廠(chǎng)模式理解
總結(jié)
以上是生活随笔為你收集整理的工厂模式理解_工厂模式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: chameleon 算法_使用Chame
- 下一篇: couchbase_适用于具有Couch