Apache Lucene的结构
不可估量的高貴的Apache軟件基金會(huì)(Apache Software Foundation)產(chǎn)生了許多重要產(chǎn)品(Ant,CouchDB,Hadoop,JMeter,Maven,OpenOffice,Subversion等),這些產(chǎn)品有助于構(gòu)建我們的數(shù)字世界。 Lucene也許是一個(gè)鮮為人知的瑰寶,它“……提供基于Java的索引和搜索技術(shù),以及拼寫(xiě)檢查,命中突出顯示和高級(jí)分析/令牌化功能。” 盡管從標(biāo)題上避開(kāi)了,Lucene還是許多Apache(和第三方)項(xiàng)目中一個(gè)安靜但不可或缺的組成部分。
讓我們看一下這個(gè)出色且非常成功的產(chǎn)品的基礎(chǔ)結(jié)構(gòu)。
在開(kāi)始之前,請(qǐng)先進(jìn)行以下四個(gè)警告。
因此,為了生意……
崛起 …
圖1:Lucene 1.4.3版的軟件包結(jié)構(gòu)。
圖1顯示了仍在歸檔的Lucene的最早版本之一,版本1.4.3。 回想一下,簡(jiǎn)單的結(jié)構(gòu)測(cè)試表明隨機(jī)選擇了一個(gè)程序包,并詢問(wèn):“如果該程序包發(fā)生更改,它最有可能影響其他哪些程序包?”
以索引為例。 很明顯的QueryParser和跨度都依賴于它,因此可以通過(guò)任何變化指標(biāo)受到影響,而曲線顯示, 搜索就靠它呢。 這種易于識(shí)別的依賴性體現(xiàn)了整個(gè)人物的特征,使其結(jié)構(gòu)合理。
布拉沃(Bravo),露西恩(Lucene),您的開(kāi)局很好。
圖2:Lucene 2.0版的程序包結(jié)構(gòu)。
圖2顯示了2.0版(請(qǐng)注意,我們不會(huì)研究每個(gè)發(fā)行版,而是沿著整個(gè)發(fā)行路徑均勻地劃分里程碑),并且互連的簡(jiǎn)單性仍在繼續(xù)。 盡管方法的數(shù)量從1.4.3的1,637版增加到2.0的2,085版,但程序包的數(shù)量卻從11種減少到10種。這促使有效耦合效率從41%降至37%略有下降,但是好的設(shè)計(jì)原則顯然可以精通此系統(tǒng)。
圖3:Lucene 2.4版的軟件包結(jié)構(gòu)。
上面的圖3中呈現(xiàn)的2.4版本雖然遠(yuǎn)沒(méi)有明顯的不良結(jié)構(gòu),但是卻顯示出苦惱的最初跡象。
沒(méi)錯(cuò),許多包裹與鄰居之間有著明顯的聯(lián)系。 但是現(xiàn)在有些沒(méi)有。 特別是搜索和索引似乎已經(jīng)陷入彼此的事務(wù)中。
但是,這種輕微的結(jié)構(gòu)退化掩蓋了幕后發(fā)生的動(dòng)蕩變化。 在2.0版有2,085個(gè)方法的地方,2.4版的大小增加了一倍多,達(dá)到4,176個(gè)方法。 在版本2.0僅具有9,767個(gè)傳遞依賴項(xiàng)的情況下,版本2.4在繁重的48,370個(gè)傳遞依賴項(xiàng)之下下垂。 正如我們將看到的那樣,某些結(jié)構(gòu)性裂縫已在方法級(jí)別上深層拉開(kāi),以觸發(fā)依賴關(guān)系的五倍增長(zhǎng),這是Lucene的程序員從未發(fā)現(xiàn)或密封的裂縫,并且困擾著以后的修訂。
不僅依賴關(guān)系的數(shù)量急劇增加,而且程序的深度(其傳遞依賴關(guān)系的平均長(zhǎng)度)也增加了,從2.0版的7升級(jí)到2.4版的8.6,不僅在漣漪效應(yīng)可能會(huì)撲朔迷離,但將這些音軌延伸到更遠(yuǎn)的地方以分流虛假的沖擊。
盡管如此,這種結(jié)構(gòu)仍然沒(méi)有解決任何問(wèn)題。 專注于設(shè)計(jì)可以恢復(fù)早期版本所具有的簡(jiǎn)單性。
圖4:Lucene 3.0版的程序包結(jié)構(gòu)。
las,版本3.0(如上圖4所示)似乎繼續(xù)以很小的幅度下降。 再次,圖4并沒(méi)有呈現(xiàn)出一種不可挽回的結(jié)構(gòu):我們可以通過(guò)拆開(kāi)包裝來(lái)了解它們之間如何相互連接。 但是,這項(xiàng)任務(wù)變得更加困難。
分析和跨度都被搜索和索引所吸引。 預(yù)測(cè)更改這四個(gè)軟件包中任何一個(gè)的影響現(xiàn)在似乎需要對(duì)所有其他軟件包進(jìn)行自動(dòng)調(diào)查。
為增加互連性做出的貢獻(xiàn)是在此修訂版中增加了800種方法。 即使傳遞依存關(guān)系的數(shù)量已下降到46,917個(gè),但平均長(zhǎng)度仍再次增加,這次是9.3個(gè)。
系統(tǒng)的結(jié)構(gòu)是否超出希望? 一點(diǎn)也不:許多軟件包與同事之間都享有明確的依賴關(guān)系。 然而,即將到來(lái)的是版本3.5和大量傳遞依賴,盡管不是立即致命,但證明對(duì)所有藥物都具有抗藥性。
還有秋天……
圖5:Lucene 3.5版的程序包結(jié)構(gòu)。
令人欣慰的是,如上圖5所示,版本3.5引入了額外的三個(gè)軟件包(總數(shù)達(dá)到18個(gè)),以嘗試分發(fā)和分離系統(tǒng)的功能。 慷慨的還可能會(huì)提出,盡管軟件包的結(jié)構(gòu)已從上一版明顯地再次衰減了,但這種衰減仍然在一定程度上是局部的:壞男孩分析 , 跨度 , 搜索和索引繼續(xù)使Lucene鎮(zhèn)表現(xiàn)良好的其他人群感到恐懼。
但是慷慨到此為止。
盡管僅增加了1800種方法,修訂版3.5的傳遞依賴項(xiàng)數(shù)量卻猛增到109,357,并且這些依賴項(xiàng)的平均長(zhǎng)度達(dá)到11種方法,這在整個(gè)演進(jìn)中都是可悲的最大值。 考慮到結(jié)構(gòu)復(fù)雜性的顯著提高,我們想知道封裝設(shè)計(jì)的外觀如何,以及它的協(xié)調(diào)性確實(shí)是短暫的,因?yàn)閼?yīng)變最終破壞了下一個(gè)修訂里程碑中的所有控制外觀。
圖5:Lucene 4.0版的程序包結(jié)構(gòu)。
如圖5所示,修訂版4.0在以前的修訂版中增加了1600種方法,使總數(shù)增加到8474,并且傳遞依賴項(xiàng)的數(shù)量相對(duì)適度地增加到116211,但是從圖中可以看出,發(fā)生了一些可怕的事情。
先前版本的Swift發(fā)展的互連性突然系統(tǒng)化,導(dǎo)致結(jié)構(gòu)內(nèi)陷到可怕的纏結(jié)的依賴關(guān)系中,這使得代碼影響預(yù)測(cè)變得非常不可靠。
的確,此修訂版增加了另外兩個(gè)軟件包-將潛在的耦合效率提高到43%-并將傳遞依賴項(xiàng)長(zhǎng)度(略)減少到10.4,但是控制如此大量的傳遞依賴項(xiàng)的巨大努力只是破壞了系統(tǒng)。 它不會(huì)恢復(fù)。
圖6:Lucene 4.5版的軟件包結(jié)構(gòu)。
在圖6所示的修訂版4.5中,一些英勇的行動(dòng)將傳遞依賴項(xiàng)的數(shù)量減少到106,242,同時(shí)仍將方法的數(shù)量增加到9,562,也許某些軟件包設(shè)法使自己遠(yuǎn)離系統(tǒng)上手動(dòng)旋轉(zhuǎn)的貪婪黑洞。核心。 但是工作太少了,太遲了。
圖7:Lucene 5.0版的程序包結(jié)構(gòu)。
如圖7所示,修訂版5.0嘗試通過(guò)刪除200種方法來(lái)馴服野獸,但這奇怪地導(dǎo)致可傳遞依賴項(xiàng)的數(shù)量再次增加到113,556。
版本5.0看起來(lái)和版本4.5一樣糟糕嗎? 好吧,也許不是。 看起來(lái)有點(diǎn)干凈。 但是,我們不應(yīng)該讓這種情況使我們對(duì)圖7所示的巨大混亂視而不見(jiàn):該系統(tǒng)痛苦不堪。 預(yù)測(cè)更改任何這些中央軟件包的成本已經(jīng)變得很困難。
為什么?
要了解破壞系統(tǒng)初始結(jié)構(gòu)完整性的原因,我們必須檢查3.5版。 再次,這看起來(lái)可能不是最糟糕的結(jié)構(gòu),但是此修訂版預(yù)示了最終導(dǎo)致破產(chǎn)的變化。
主要的變化不僅是規(guī)模上的變化:更大的系統(tǒng)不一定會(huì)陷入不良的結(jié)構(gòu)。 修訂版3.5將方法數(shù)量增加了35%,但修訂版2.4將方法數(shù)量增加了100%以上,而不會(huì)破壞整個(gè)組織。
相反,罪魁禍?zhǔn)资莻鬟f依賴項(xiàng)的數(shù)量及其在系統(tǒng)中的分布。
修訂版3.5中引入的新的傳遞依賴項(xiàng)數(shù)量驚人,從46,917增至109,357。 這使依賴方法比達(dá)到了動(dòng)脈硬化16。
圖8:比較Lucene的方法傳遞依存關(guān)系比率。
依賴于方法的比率已經(jīng)太高了。 但是,在以前的版本中,這些可傳遞依賴項(xiàng)在很大程度上只限于一個(gè)或兩個(gè)程序包。 在版本3.0中,所有傳遞方法依賴項(xiàng)的95%終止于其原始包或僅一個(gè)依賴項(xiàng)的包中。 這給了希望,從某種意義上講,變更可能會(huì)將自己限制在接近原點(diǎn)的區(qū)域,而很少有變更能夠溢出到整個(gè)系統(tǒng)中,并且無(wú)法進(jìn)行成本預(yù)測(cè)。
但是,修訂版3.5看到該數(shù)字暴跌至75%。 這意味著所有修訂版3.5的傳遞依賴項(xiàng)中有25%溢出到三個(gè)或更多程序包中。 將這兩個(gè)因素結(jié)合在一起,就可以發(fā)現(xiàn)有33,000多個(gè)依賴項(xiàng)需要等待遠(yuǎn)遠(yuǎn)超出其起源的彈射變化。 最重要的是,這注定了產(chǎn)品會(huì)進(jìn)一步結(jié)構(gòu)衰減。
圖9:Lucene傳遞依賴項(xiàng)所占的百分比,少于3個(gè)包。
然后,這結(jié)束了對(duì)Lucene包級(jí)別結(jié)構(gòu)的檢查。 我們是否應(yīng)該深入研究套餐級(jí)別? 我們是否應(yīng)該梳理各個(gè)軟件包以檢查各種類別的星座? 不行 。根據(jù)Blighttown的推論 ,如果包裝級(jí)別的結(jié)構(gòu)不好,我們不希望在下面找到鉆石。 所以我們不會(huì)。
最終成績(jī)
讓我們嘗試對(duì)Lucene的結(jié)構(gòu)進(jìn)行客觀評(píng)分(其最終修訂版本此處為5.0)。
我們將使用四個(gè)因素的平均值。 第一個(gè)度量Lucene試圖限制可能形成的依賴關(guān)系數(shù)量的嘗試。 第二和第三次嘗試捕獲傳遞依賴項(xiàng)的長(zhǎng)度,第四次嘗試捕獲傳遞依賴項(xiàng)的數(shù)量。 當(dāng)然,大型系統(tǒng)總會(huì)比小型系統(tǒng)具有更多的依賴關(guān)系,因此我們不能僅僅因?yàn)橄到y(tǒng)A的依賴關(guān)系少就說(shuō)系統(tǒng)A的結(jié)構(gòu)比系統(tǒng)B更完善。 取而代之的是,我們必須通過(guò)標(biāo)準(zhǔn)化大小或使測(cè)量在某種意義上具有自參考性,得出可以公平比較的測(cè)量。
首先,我們將測(cè)量其絕對(duì)理想效率:這將分析結(jié)構(gòu)的潛在耦合 ,并基本詢問(wèn)封裝了多少種方法而不使用其他方法,因此可以想象會(huì)創(chuàng)建多少依賴關(guān)系。 如果將每種方法都放在一個(gè)類中,則每種方法對(duì)彼此都是可見(jiàn)的,因此效率為0%。 隨著將更多方法設(shè)為私有并放入單獨(dú)的包私有類中,其價(jià)值將不斷提高,從而使方法之間的封裝越來(lái)越多。
Lucene得分為44%,表明它至少已嘗試封裝其功能,但是可以做更多的事情。
其次,我們將以一種允許程序之間公平比較的形式來(lái)衡量Lucene的傳遞依賴項(xiàng)的長(zhǎng)度。 為此,我們將使用CDF圖來(lái)顯示Lucene的傳遞方法依賴關(guān)系占其最長(zhǎng)傳遞依賴關(guān)系的百分比。
圖10:Lucene的傳遞依賴CDF。
在上面的圖10中,我們看到Lucene的傳遞依存關(guān)系的一半短于最長(zhǎng)的傳遞依存關(guān)系的長(zhǎng)度的45%。 這是不好的。 系統(tǒng)對(duì)紋波效應(yīng)的抵抗力取決于其大部分依賴關(guān)系是否短暫。 例如, JUnit的傳遞依賴的一半僅占其最長(zhǎng)依賴關(guān)系長(zhǎng)度的30%。
當(dāng)我們需要一個(gè)具有改進(jìn)結(jié)構(gòu)的數(shù)字時(shí),我們將使用100減去該數(shù)字,因此Lucene將獲得100 – 45 = 55的分?jǐn)?shù),該值應(yīng)接近70。
我們將要討論的第三個(gè)因素是:跨越兩個(gè)或更少程序包的方法所占的百分比,這個(gè)數(shù)字為75.5%。 聽(tīng)起來(lái)不錯(cuò),但是使用現(xiàn)代結(jié)構(gòu)技術(shù) ,幾乎沒(méi)有理由將該值小于90%。
最后,我們需要一個(gè)因素來(lái)衡量系統(tǒng)中有多少依賴項(xiàng),因?yàn)橐蕾図?xiàng)的數(shù)量越少越好。 為了規(guī)范化大小,我們要測(cè)量每個(gè)方法的方法相關(guān)性數(shù)量。 不幸的是,在這里我們必須估算出行業(yè)最低的分?jǐn)?shù)。 一些研究表明25似乎是一個(gè)合適的數(shù)字:如果系統(tǒng)每個(gè)方法包含25個(gè)以上的依賴項(xiàng),則該系統(tǒng)的結(jié)構(gòu)是如此糟糕,以至于所有其他所有其他指標(biāo)都失去了重要性。
前面我們看到,Lucene每個(gè)方法有12個(gè)巨大的依賴關(guān)系; 因此我們將使用的數(shù)字為25-12 = 13,以25的百分比表示,得出52%。 如圖8所示,其他系統(tǒng)的每種方法的依賴關(guān)系低至6,這個(gè)指標(biāo)的收益率超過(guò)70%。
這使得Lucene的最終得分為226.5 / 400分,即57%。 憑借堅(jiān)定的結(jié)構(gòu)原則,現(xiàn)代程序的分?jǐn)?shù)很容易超過(guò)80%,所以這是一個(gè)很差的分?jǐn)?shù),表示,很糟糕的結(jié)構(gòu)。 Lucene在本系列到目前為止所分析的系統(tǒng)的排行榜中排名倒數(shù)第二。
| 因子 | 得分了 |
| 絕對(duì)勢(shì)偶效率% | 44 |
| 100 –(最長(zhǎng)依賴關(guān)系長(zhǎng)度的一半,即一半系統(tǒng)短于該長(zhǎng)度) | 55 |
| 方法傳遞相關(guān)性百分比,范圍不超過(guò)2個(gè)軟件包 | 75.5 |
| ((25-(每個(gè)方法的傳遞方法依賴項(xiàng)數(shù)量)/ 25),以25的百分比表示 | 52 |
| 平均 | 57% |
表1:Lucene 5.0的結(jié)構(gòu)評(píng)估。
摘要
| 程序 | 結(jié)構(gòu)得分 |
| Spoiklin Soice | 84% |
| JUnit的 | 67% |
| Struts | 67% |
| FitNesse | 62% |
| 彈簧 | 60% |
| Lucene | 57% |
| 螞蟻 | 24% |
表2:Lucene在排行榜上的位置。
可以做的更好。
翻譯自: https://www.javacodegeeks.com/2015/05/the-structure-of-apache-lucene.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的Apache Lucene的结构的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 芝士和奶酪一样吗 芝士和奶酪是不是一样的
- 下一篇: 难题:嵌套computeIfAbsent