依賴注入–手動方式

依賴注入是一種將行為與依賴解決方案分開的技術。 用簡單的話來說,它允許開發人員定義具有特定功能的類,這些功能取決于各種協作者,而不必定義如何獲取對這些協作者的引用。 以此方式,實現了各個組件之間的解耦,并且通常引入了更簡潔的代碼。 更具體地說,一個組件僅列出必要的服務,而不是對依賴項進行硬編碼,而在運行時,一個外部獨立的組件將提供對這些服務的訪問。 我們不應忘記,依賴注入只是控制反轉的一種特殊形式,其中關注點的反轉是獲取所需依賴關系的過程。 前述技術的參考文章是Martin Fowler的 “控制容器的倒置和依賴注入模式” 。

為了注入依賴關系,已經出現了許多框架,最著名的是Spring和Guice (請參閱JavaCodeGeeks Spring相關文章)。 但是,對于小型項目使用整個框架無疑是一個過大的殺傷力。 我們的JCG合作伙伴之一, “按代碼死亡”博客的作者,撰寫了有關如何手動處理依賴項注入的小介紹。 讓我們看看他怎么說?

在另一篇文章中, “我真的需要單身人士嗎?” ,我寫了有關Singleton設計模式引入的問題的文章。 通過getInstance()方法訪問單個唯一實例時,Singleton會變相充當全局變量,并引入緊密耦合和不必要的依賴關系。 我收到了讀者的兩個直接問題:

單例應該僅與依賴注入框架一起使用嗎?
如果通過getInstance()訪問Singleton創建緊密耦合,則通過new()創建任何其他類的實例也將導致緊密耦合。 那么,如何創建一個保持松散耦合的對象?

根據我的理解,依賴注入是這兩個問題的答案。 但是,這并不要求使用框架。 依賴注入首先是一個概念,然后是一個框架。 當所討論的應用程序很小時,我們總是可以通過手動注入依賴項來滿足需求,而無需使用諸如Spring之類的框架。

在任何Java應用程序中,我們都會反復遇到兩個事件:

  • 對象創建
  • 對象之間的交互–業務邏輯

但是,通常我們將兩者混為一談,從而導致緊密耦合和不必要的依賴關系,這反過來又使維護以及單元測試變得痛苦。 讓我嘗試使用一個非常簡單的示例來解釋它:

class MyClass {private A a; //A is an interfaceprivate B b; //B is an interface//Object creation within constructorMyClass(A a, B b) {  a = new AImpl(); //AImpl is the concrete impl of Ab = new BImpl(); //BImpl is the concrete impl of B}//Application logic lies within this methodpublic void doSomething() {//Do A specific thing//Do B specific thingC c = new CImpl(); //Object creation within the method.//Do C specific thing}
}

此類的問題是:

  1. 它無法將對象創建與業務邏輯分開,從而導致緊密耦合。
  2. 這里已經完成了“實現編程”,而不是接口。 明天,如果需要A,B或C的不同實現,則必須更改類中的代碼。
  3. 測試MyClass需要首先測試A,B,C。

讓我嘗試解決問題:

class MyClass {private A a;private B b;private C c;MyClass(A a, B b, C c) {//Only Assignmentthis.a = a;this.b = b;this.c = c;}//Application Logicpublic void doSomething() {//Do A specific thing//Do B specific thing//Do C specific thing}
}//The Factory
class MyFactory {public MyClass createMyClass() {return new MyClass(new AImpl(), new BImpl(), new CImpl());}
}class Main {public static void main(String args[]) {MyClass mc = new MyFactory().createMyClass();mc.doSomething();}
}

在這里已經實現了什么:

1.構造函數沒有new():
沒有在MyClass的構造函數中創建對象。 構造函數僅用于字段(A,B,C)分配。 在這里,構造函數要求依賴項作為參數,但不創建它們(這是依賴項注入的最簡單定義)。 但是,可以在構造函數內創建簡單的Collection對象(如ArrayList,HashMap或value / leaf對象,如Person / Employee)(即應用程序內的對象,這些對象又不會創建其他對象)。 構造函數不得用于任何其他操作,例如I / O,線程創建等。

根據經驗法則,任何對象都應僅保留對其直接完成工作所需的其他對象的引用(這稱為Demeter法則)。 例如,如果MyClass需要其他名為X的類,則MyClass的構造函數應直接要求X。不應要求其他工廠F可以返回X的實例。違反“ De??meter法則”將導致不必要的依賴性因此,如果您發現多個Dot(。)運算符,請當心-那里發生了非法事件。

2. Factory(MyFactory)負責對象的創建和連接:
所有新的操作員(90%-99%)應屬于工廠。 它應負責為應用程序創建整個對象圖,并應根據聲明的依賴關系關聯(連接)不同的對象(例如,MyClass需要A,B,C等)。 它不應包含任何其他內容-不應包含任何其他邏輯(沒有I / O,線程創建等)。

明天如果C開始依賴于其他稱為D的東西,則只會影響C和工廠,而不會影響整個對象圖(C必須引入重載的構造函數,并且工廠必須合并對象實例化以及與對象接線相關的更改) 。

對于大型應用程序,當然可能會有多個工廠。 在這里,經驗法則是一個工廠應該實例化具有相同壽命的所有對象。

3.對象的創建與業務邏輯是分開的:
MyClass現在是業務邏輯持有人。 它沒有任何new()。 甚至,它也不了解用于業務邏輯的具體實現(即,它了解A,但不了解AImpl,即“接口程序而不是實現程序”)。

您一定已經開始認為我是在Singleton的背景下開始討論的。 手動依賴項注入如何處理Singleton? 如何創建一個Singleton(減去緊密耦合,隱藏的依賴關系等)并在需要時訪問它? 令人驚訝的是,我們的示例中已經包含三個Singleton-AImpl,BImpl,CImpl。 如果工廠只負責創建Class的一個實例(通過僅調用new()一次),則其為Singleton。 是不是 然后,工廠可以將該依賴關系形式的唯一實例傳遞給需要它的所有其他對象。

4.那么,我們在哪里?
業務邏輯持有者MyClass的業務需要A,B和C。 它不會創建它們,而是要它們(依賴項)。 工廠(MyFactory)創建這些依賴關系并將其關聯到MyClass。 但是,誰創造了工廠? 當然是主要方法(應用程序啟動器:-)。 讓我再重復一遍這個故事:main方法首先實例化工廠,工廠反過來實例化對象圖,每個Object聲明其依賴關系,最后main方法本身設置滾動-通過調用MyClass的doSomething()啟動應用程序,即。 這些對象開始互相交談,執行日常業務。

讓我再重復一次: 創建工廠,使用工廠創建應用程序,然后啟動應用程序! 對于大規模應用程序,可以通過像Spring,Google Guice等依賴注入框架來實現相同的目的。當然,它們還將帶來許多其他好處。 但是,對于中小型應用程序,可以手動制作依賴項注入,從而使應用程序松散耦合,更易于維護,并且當然可以進行單元測試。

相關文章 :
  • 使用Spring AspectJ和Maven進行面向方面的編程
  • JBoss 4.2.x Spring 3 JPA Hibernate教程
  • GWT Spring和Hibernate進入數據網格世界
  • 建立自己的GWT Spring Maven原型
  • GWT 2 Spring 3 JPA 2 Hibernate 3.5教程– Eclipse和Maven 2展示
  • 使用Spring使用Java發送電子郵件– GMail SMTP服務器示例

翻譯自: https://www.javacodegeeks.com/2010/12/dependency-injection-manual-way.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/374684.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/374684.shtml
英文地址,請注明出處:http://en.pswp.cn/news/374684.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

一個疏忽引發的思考!(strerror)

前幾天寫代碼因為自己的疏忽導致一遍又一遍的Segmentation fault (core dumped)。該問題是因為strerror(errno)返回的指針指向非法的內存導致程序打印錯誤時崩潰。 嘗試數次無果,為了進度。簡單粗暴的換成了perror(str)。今天忙里偷閑&#x…

力扣面試題 01.08. 零矩陣

編寫一種算法,若M N矩陣中某個元素為0,則將其所在的行與列清零 代碼一思路: 第一次遍歷時記錄,用兩個布爾類型數組標記行和列中是否有0元素; 第二次遍歷時置零 class Solution {public void setZeroes(int[][] matr…

Java最佳實踐–字符串性能和精確字符串匹配

在使用Java編程語言時,我們將繼續討論與建議的實踐有關的系列文章,我們將討論String性能調優。 我們將專注于如何有效地處理字符串創建, 字符串更改和字符串匹配操作。 此外,我們將提供我們自己的用于精確字符串匹配的最常用算法的…

mac下開發環境常用操作與命令

【1】 修改hosts文件 vim /private/etc/hosts轉載于:https://www.cnblogs.com/zsmynl/p/4714492.html

keil里面填數據

編譯后寄存器和堆棧的內存數據可以直接寫進去的。 寄存器,雙擊就可以,注意里面是十六進制 堆棧,也是十六進制,八位的 00 00 00 00 ,但這個是從右到左的,比如0x00000006 應該填 06 00 00 00 把數據取出來 取…

力扣498. 對角線遍歷

給你一個大小為 m x n 的矩陣 mat ,請以對角線遍歷的順序,用一個數組返回這個矩陣中的所有元素。 代碼思路:以第一行和右邊最后一列作為每輪的開始元素,先用temp存儲,全部按 從左上到右下 的順序遍歷,但是…

調試生產服務器– Eclipse和JBoss展示

您是否編寫有錯誤的代碼? 不,當然不。 對于我們其余的確實會編寫帶有錯誤的代碼的凡人,我想解決一個非常敏感的問題:調試在生產服務器上運行的應用程序。 因此,您的應用程序已準備好進行部署。 單元測試全部成功&…

ubuntu server獲取并自動設置最快鏡像的方法

一,安裝方法1 add-apt-repository ppa:ossug-hychen/getfastmirrorapt-get install getfastmirror 如果添加了臨時源,這樣移除add-apt-repository --remove ppa:ossug-hychen/getfastmirror 二,安裝方法2 wget -O getfastmirror-master.zip h…

linux之x86裁剪移植---ffmpeg的H264解碼顯示(420、422)

在虛擬機上yuv420可以正常顯示 ,而945(D525)模塊上卻無法顯示 ,后來驗證了directdraw的yuv420也無法顯示 ,由此懷疑顯卡不支持 ,后把420轉換為422顯示。420顯示如下:/* 編譯命令:arm…

Spring依賴注入技術的發展

回顧Spring框架的歷史,您會發現實現依賴注入的方式在每個發行版中都在增加。 如果您使用該框架已經超過一個月,那么在這篇回顧性文章中可能不會發現任何有趣的東西。 除了Scala中的最后一個示例,沒有其他希望,這種語言在Spring中意…

JS encode decode

網上查到的全都是escape,和需要的編碼不是一回事,好不容易找到的結果 保存下來以備以后使用js對文字進行編碼涉及3個函數:escape,encodeURI,encodeURIComponent,相應3個解碼函數:unescape,decodeURI,decodeURIComponen…

流媒體服務器 筆記

1.sip服務器回SBC Port Unreachable 說明轉碼器接收RTCP的端口沒有打開 轉載于:https://www.cnblogs.com/luoyinjie/p/7219359.html

力扣151. 翻轉字符串里的單詞

給你一個字符串 s ,逐個翻轉字符串中的所有 單詞 。 單詞 是由非空格字符組成的字符串。s 中使用至少一個空格將字符串中的 單詞 分隔開。 請你返回一個翻轉 s 中單詞順序并用單個空格相連的字符串。 沒思路,看到的官方給的,簡潔明了&…

Spring 3 HornetQ 2.1集成教程

通過Spring框架使用JBoss的新超高性能消息傳遞系統。 HornetQ是一個開放源代碼項目,用于構建多協議,可嵌入,非常高性能的集群異步消息傳遞系統。 它是用Java編寫的,并且可以在具有Java 5或更高版本運行時的任何平臺上運行。 Horn…

B/S和C/S架構圖解

軟件:B/S和C/S兩種架構模式。接下來用三張圖片解釋,什么是B/S什么是C/S。 圖片一:軟件架構模式 圖片二:C/S結構模式 圖片三:B/S結構模式 相信圖解勝過冗長文字的解釋,什么是B/S什么是C/S一目了然。 轉載于:…

557. 反轉字符串中的單詞 III

給定一個字符串&#xff0c;你需要反轉字符串中每個單詞的字符順序&#xff0c;同時仍保留空格和單詞的初始順序。 class Solution {public String reverseWords(String s) {StringBuffer res new StringBuffer();int length s.length();int i 0;while(i < length){int …

休眠陷阱

我已經使用Hibernate已有一段時間了&#xff0c;當我一段時間不使用Hibernate項目時&#xff0c;發現自己犯的錯誤與上次相同。 因此&#xff0c;這是我的監視清單&#xff0c;希望對其他人也有用。 實現hashCode和equals 一般而言&#xff0c;應該始終實現這些方法&#xff…

HDU 5371 Hotaru's problem (Manacher,回文串)

題意&#xff1a;給一個序列&#xff0c;找出1個連續子序列&#xff0c;將其平分成前&#xff0c;中&#xff0c;后等長的3段子序列&#xff0c;要求【前】和【中】是回文&#xff0c;【中】和【后】是回文。求3段最長為多少&#xff1f;由于平分的關系&#xff0c;所以答案應該…

bash 與 dash

Ubuntu 的 bash和dash的區別 什么是bash &#xff1f; Bash(GNU Bourne-Again Shell)是許多Linux平臺的內定Shell&#xff0c;事實上&#xff0c;還有許多傳統UNIX上用的Shell&#xff0c;像tcsh、csh、ash、bsh、ksh等 等&#xff0c;Shell Script大致都類同&#xff0c;當您學…

350. 兩個數組的交集 II

給你兩個整數數組 nums1 和 nums2 &#xff0c;請你以數組形式返回兩數組的交集。返回結果中每個元素出現的次數&#xff0c;應與元素在兩個數組中都出現的次數一致&#xff08;如果出現次數不一致&#xff0c;則考慮取較小值&#xff09;。可以不考慮輸出結果的順序。 來源&a…