java-間接引用

引用的必要

一個文件實現一個複雜功能的時代已經過去了,甚至一個工程實現一個項目都逐漸被淘汰。

限於層級的劃分、項目的管理、功能的擴展等因素,在程序的設計之初,就有了引用的概念。

使用既定的方式,去使用已經完成的功能或者對象。

部門間的流轉、模塊間的導入都是如此,僅僅關注於自身的邏輯管理,而其他部分只關注接口。

諸多的編程語言中,基本的共同點,就是包、模塊的引入。

Go語言中,方法間存在兩種引用:值傳遞和引用傳遞。

一個大對象,佔據內存爲S,如果是值傳遞,經過n個操作方法,內存佔用爲(n+1)×S(n +1) \times S

但是,如果使用地址傳遞,也就是地址引用,消耗內存爲S+4×nS + 4 \times n

不論是功能還是其他方面,引用都是大有用處,也無處不在。

奇妙的對象

面向對象的模式的優缺點不用再討論,我也沒能力置喙,只是說說它和引用的奇妙關聯。

面向對象的封裝模式,更提高了內聚,但是引出一個本質問題:多層引用

我們通過模塊引入一個類,實例化類之後通過對象引用方法。

尤其重要的是,我們更依賴於對象的引用,這就把引用的本質,或者面向對象的本質給顯露出來。

普遍的引用,通過方法的傳遞,或者模塊的導入即可完成,但是面向對象中間還夾雜了實例化這個步驟。

總結一下,面向對象的幾個繁瑣點

  • 個體依賴性

模塊可以直接引用、方法可以直接調用,但是面向對象中依賴的並不是直接的外部接口,而是依賴的具體對象。

即使是同一個類,由於參數的不同,相同的方法之間的差異性也非常巨大,不存直接引用這種說法。

  • 引入複雜性

由於前述的一點,當涉及多個對象組合的功能的時候,如何引入這些依賴的對象。

加上其他模塊對於基礎對象的相同的引入,不可能由某一個特定的使用類來具體的實例化。

同時,不管由構造器還是外部方法進行設置,都顯得十分笨拙。


或者還有其他原因,但都大同小異,那就是:面向對象帶來了引入的動態性質。

之前的引入,都是靜態的,但是基於對象而非類的依賴,尤其是對象的封裝特性,我們不可能做到統一的引入。

勢必,要有那麼一個東西,支持、簡化、統一我們的對象的引用。

注入(DI)

模塊和方法都是靜態的,對其接口即可,對象確實動態的,必須指定個體。

而且由於可能的多方面的引用,無法交給任何一個調用類來進行實例化管理,必須存在一箇中心的容器,去維護這些基礎的素材。

最後,讓對象,和其他語言中的模塊一樣,成爲一種靜態的,可無歧義的直接進行引用。


每種語言,支持的都是基礎的靜態引用,而java中的辦法,或者說spring的方案是:使用一個對象容器,來進行維護管理

然後通過注入這種方式,來模仿導入的過程。也即是,你說你需要,我一個個給你們填充。

看看一個文件中高達十幾個的類引用,想到一個個的實例化的恐懼,想到幾十個類之間的交叉引用,慶幸。


幾十個的get/set,誰都會對代碼喪失興趣。

控制(IOC)

然後,接踵而來的更重要的問題,管理的對象哪裏來。

如果說藉助容器,我們自己去挨個註冊,自己去實例化,不說多麼無味和重複,只是,有必要麼。

通過反射,或者其他什麼辦法,讓容器自主的能夠去創建、管理對象。

減少失誤,提高開發進度,尤其死板的嚴格的管控條例,獲得更準確的服務保障,這就是IOC的極大優勢。

切面(AOP)

不得不說,基於對象引用的繁雜操作讓人厭煩,但是,其所帶來的操作空間的確巨大。

對於一個基礎的功能,如果我們想要稍微修飾一下,就會顯得十分雞肋

  • 方法包裝

可以寫方法進行包裝,但是卻可能時常更換,浪費人力,切效用不大

  • 操作包裹

操作時候去修飾,沖淡邏輯的緊密性,分散精力,冗餘垃圾代碼


不論採取什麼方式都顯得雞肋----但是,java中這種問題不復存在。

moduleplatformprocesswraperloadcallwrappermoduleplatformprocess

如上,雞肋讓我們不論從模塊還是程序的角度,都無法保證純淨。

modulejvmcontainerprocessloadinstance and wrappercallmodulejvmcontainerprocess

多出來的中間過程,讓我們可以盡情的去定製所需要的即將引用的對象及其方法。

在每個階段都能夠保證自身的純淨、邏輯的聚合。

其中的從加載到容器的階段,正是切面(定製)的活動空間。

由於jvm是基於class的中間語言的平臺,從javaclass的步驟,也是這一步的領域。

因此,切面在於已經加載對象的重新定製,還有javaassist等基於字節碼的包裝功能。

不論是加載即包裝,還是引用即包裝,都是對象引用所提供的定製化的操作空間。

fileclassobjectcontainerprocessloadinstancemanagercallfileclassobjectcontainerprocess

忽略具體細節,把class字節碼文件等同於java的內容,就可以統一理解。

注意:class的直接定製,由於不存在更多的聯結特性,效能優於基於對象的包裝方案。

操作的空間

如果非直接的流程,在中間的傳輸過程中,就可能存在更多可能的操作,提供更多的使用空間。

ribbon的負載均衡,正是由於註冊中心的非直接調用,才得以實現。

微服務中的小模塊,管理和調用,正如java中的對象引用的管理,容器中心也就變成了服務中心。

簡單的引用,其本質,天差地別。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章