intellij idea_IntelliJ IDEA内部设计
intellij idea
IntelliJ IDEA的第一個版本于2001年1月發布,當時它是第一個集成了高級代碼導航和代碼重構功能的Java IDE之一。
2009年,JetBrains開源了其社區版本 。 從那時起,創建了許多基于它的IDE,例如Google的Android Studio。
讓我們使用JArchitect進入Intellij IDEA的社區版本,并發現一些內部設計選擇。
1.模塊化
Intellij IDEA使用許多項目進行了模塊化。 主要的是“想法”。 實用程序類在“ util”項目中實現,“ openapi” jar包含開發Intellij IDEA插件所需的類型。
這是Intellij IDEA項目的列表,以及有關其類型的一些統計信息:
每個項目都包含許多軟件包以使其代碼庫模塊化,并且采用了按功能打包的方法。
逐功能包使用程序包來反映功能集。 它將與單個功能(僅該功能)相關的所有項目放置在單個目錄/程序包中。 這導致包裝具有高內聚力和高模塊化性,并且包裝之間的耦合最小。 緊密協作的項目彼此相鄰放置。
例如,這里有一些來自idea項目的軟件包,這些軟件包顯示了按功能分組的類型。
2. Intellij IDEA開發人員廣泛使用GoF設計模式
設計模式是一種軟件工程概念,描述了針對軟件設計中常見問題的重復解決方案。 GoF模式是最受歡迎的模式。
Intellij IDEA開發人員廣泛使用GOF模式。 這是源代碼中使用的一些方法。
2.1工廠
使用工廠來隔離實例化邏輯并增強內聚力很有趣。 這是源代碼中定義的工廠列表:
實施了許多工廠; 這里有一些是從TextEditorHighlihtingPassFactory繼承的。
2.2適配器
適配器模式充當兩個不兼容接口之間的橋梁。 這種設計模式屬于結構模式,因為該模式結合了兩個獨立接口的功能。
Intellij IDEA源代碼中實現了許多適配器:
2.3裝飾器
裝飾器模式可用于擴展(裝飾)某個對象的功能,而無需更改其結構。 在Intellij IDEA中實現了許多裝飾器。
2.4代理
在最一般的形式上,代理是一個類,充當與其他對象的接口。
例如,這是通過FieldBreakpoint和FrameVariablesTree類使用兩個代理VirtualMachineProxy和StackFrameProxy的。 使用VirtualMachineProxy接口代替實現。 但是,與FrameVariablesTree耦合的StackFrameProxyImpl并非如此。 也許可以通過重構來消除這種依賴性。
2.5門面
外觀模式隱藏了系統的復雜性,并為客戶端提供了一個接口,客戶端可以使用該接口訪問系統。 這是在Intellij IDEA中實現的CodeStyle外觀的示例。
2.6訪客
訪客設計模式是一種將算法與操作對象的結構分離的方法。
突出顯示功能是使用訪問者模式實現的。
2.7策略
在某些情況下,類僅在行為上有所不同。 在這些情況下,最好將算法隔離在單獨的類中,以便能夠在運行時選擇不同的算法。
許多類在Intellij IDEA源代碼中實現策略模式:
2.8建造者
這種模式允許客戶對象構造一個復雜的對象。 ConrtolFlowBuilder是Intellij IDEA源代碼中實現的構建器之一。
這是ControlFlowBuilder.build方法調用的方法:
3.聯軸器
低耦合是理想的,因為在一個應用程序的一個區域中進行更改將需要在整個應用程序中進行較少的更改。 從長遠來看,這可以減少與修改和向應用程序添加新功能相關的大量時間,精力和成本。
這是使用接口帶來的三個主要好處:
- 接口提供了一種定義可促進重用的合同的方法。 如果一個對象實現一個接口,則該對象將符合標準。 使用另一個對象的對象稱為使用者。 接口是對象與其使用者之間的契約。
- 接口還提供一定程度的抽象,使程序更易于理解。 接口使開發人員可以開始討論代碼行為的一般方式,而不必深入探討許多具體細節。
- 接口強制組件之間的耦合度很低,這很容易保護接口使用者免受實現接口的類中任何實現更改的影響。
在Intellij IDEA中定義了許多接口和抽象類以強制實現低耦合:
這是藍色的源代碼中這些類型在Metric視圖中的分布。
在“度量標準視圖”中,代碼??庫通過樹形圖表示。 樹映射是一種通過使用嵌套矩形來顯示樹結構數據的方法。 使用的樹結構是通常的代碼層次結構:
- 項目包含軟件包。
- 包中包含類型。
- 類型包含方法和字段。
樹狀圖視圖提供了一種有用的方式來表示CQLinq請求的結果。 藍色矩形代表此結果,因此我們可以直觀地看到請求所涉及的類型。
正如我們可以看到的那樣,接口和抽象類幾乎在所有程序包中都定義了,這對于將程序包提供的功能作為合同表示很有用。
4.凝聚力
單一責任原則規定,一個階級改變的理由不應該超過一個。 據說這樣的班級具有凝聚力。 LCOM值較高通常會指出內聚性較差的類別。 有幾個LCOM指標。 LCOM的取值范圍為[0-1]。 LCOM HS(HS代表Henderson-Sellers)的值在[0-2]范圍內。 高于1的LCOM HS值應視為警報。 以下是計算LCOM指標的方法:
LCOM = 1 – (sum(MF)/M*F) LCOM HS = (M – sum(MF)/F)(M-1)哪里:
- M是類中方法的數量(包括靜態方法和實例方法,均包括構造函數,屬性獲取器/設置器,事件添加/刪除方法)。
- F是類中實例字段的數量。
- MF是該類訪問特定實例字段的方法的數量。
- Sum(MF)是該類所有實例字段上MF的總和。
這些公式背后的基本思想可以表述為:如果一個類的所有方法都使用其所有實例字段,則該類是完全內聚的,這意味著sum(MF)= M * F然后LCOM = 0且LCOMHS = 0。
高于1的LCOMHS值應視為警報。
只有極少數的類型可以被認為是沒有凝聚力的。
5.多線程和并發
為了使Intellij IDEA更具React性,創建了許多線程,從而改善了用戶體驗。
讓我們搜索直接或間接啟動線程的所有方法:
并發邏輯被隔離在以下軟件包中:
為了促進并發開發,使用了JSR166 。
以下是jsr166 jar中使用的所有類型的列表:
6.抽象與不穩定性圖
該圖背后的想法是,程序的代碼元素越受大眾歡迎,它應該越抽象。 換句話說,就是避免過多地直接依賴于實現,而要依賴于抽象。 流行的代碼元素是指一個項目(但該想法也適用于包和類型),該項目被該程序的其他項目大量使用。
在您的代碼庫中使用非常流行的具體類型不是一個好主意。 這會引起程序中的某些痛苦區域,在其中更改實現可能會影響程序的很大一部分。 并且已知實現比抽象更容易發展。
下圖中的主序列線(點線)顯示了如何平衡抽象性和不穩定性。 一個穩定的組件將位于左側。 如果您檢查主序列,您會發現這樣的組件應該非常抽象才能接近所需的線–另一方面,如果其抽象程度較低,則將其放置在一個稱為“區域”的區域中痛”。
只有util處于痛苦區域,這并不是真正的問題。 實際上,總的來說,實用程序庫提供的實用程序類別比接口定義的功能更多。
7.開放的API和插件系統
插件的使用使您可以擴展Intellij IDEA。 提供“ openapi”罐來實現此目標。
openapi jar提供了許多接口,這些接口代表了我們可以使用并從插件擴展的所有功能。
Intellij IDEA插件包含一個或多個動作。 如以下CQLinq查詢所示,源代碼中實現了成千上萬的操作:
探索現有的已實施操作可以幫助開發人員輕松開發其自定義插件。
8.使用緩存提高性能
使用緩存是一種優化應用程序的流行方法。 Intellij IDEA使用兩個緩存管理器:
FindInProjectTask使用CacheManager接口搜索單詞。
這是FindInProjectTask.getFilesForFastWordSearch方法調用的所有方法的列表:
9.使用的外部庫
Intellij IDEA使用許多外部jar,以下是所有使用過的jar的列表:
使用外部庫時,最好檢查一下是否可以在不影響整個應用程序的情況下輕松地將第三方庫換成另一個庫。 有很多原因可以鼓勵我們更改第三方庫。 另一個庫可以:
- 有更多功能。
- 更加強大。
- 更加安全。
讓我們發現某些外部庫是否高度耦合。
搖擺:
Swing實現了一組用于構建圖形用戶界面(GUI)并向Java應用程序添加豐富的圖形功能和交互性的組件。 Swing組件完全用Java編程語言實現。 可插入的外觀使您可以創建在各個平臺上看起來相同或可以采用當前OS平臺(例如Microsoft Windows,Solaris?或Linux)外觀的GUI。
讓我們使用直接擺動組件搜索所有類型:
許多類型都直接使用擺幅組件,如下面的樹形圖所示,以藍色顯示這些類型。
通過另一個Gui框架來改變擺動并不容易。 即使Swing引起爭議,Intellij IDEA驚人的GUI證明Swing是Gui需求的不錯選擇。
凈值:
Netty是一個異步事件驅動的網絡應用程序框架,用于快速開發可維護的高性能協議服務器和客戶端。
這是使用此庫的所有類型的列表:
只有少數幾種類型直接使用它,如果我們想用另一個庫進行更改,這將非常有用。
ASM:
ASM是一個非常小且非常快的Java字節碼操作框架。 它變得非常流行,許多工具都在使用它。 我們還在工具JArchitect中使用它來分析字節碼。
這是直接使用ASM的所有類型的列表:
作為Netty,ASM的使用被隔離在某些軟件包中,我們可以輕松對其進行更改。
除了Swing之外,幾乎所有其他外部jar都不與Intellij IDEA高度耦合。
10.統計
最常用的類型
了解項目中最常用的類型很有趣。 實際上,這些類型必須經過精心設計,實施和測試。 它們發生的任何變化都可能影響整個項目。
我們可以使用TypesUsingMe指標找到它們:
但是,還有一個有趣的度量標準可以搜索流行類型:TypeRank。
通過將Google PageRank算法應用于類型的依存關系圖來計算TypeRank值。 應用中心乘以0.15使其均等,TypeRank的平均值為1。
具有較高TypeRank的類型應進行更仔細的測試,因為此類錯誤可能會造成更大的災難性后果。
這是根據TypeRank指標得出的所有流行類型的結果:
使用此度量標準,PsiElement成為了最常用的類型,而不是Project接口。
10.2最常用的方法:
10.3方法調用許多其他方法
知道使用許多其他方法的方法很有趣。 這些方法可能會揭示設計問題。 在某些情況下,需要進行重構以使其更具可讀性和可維護性。
摘要
Intellij IDEA的設計和實現非常好,使用了許多模式,并實現了許多最佳實踐。 探索其源代碼是學習如何設計和實現應用程序的實用方法。 這比只閱讀網絡上的書籍和文章來提高您的設計技能要好。
JArchitect為 所有開源Java貢獻者 提供了 專業許可 。 分析他們的代碼庫可能很有用。 因此,如果您想嘗試一下,請 在此處 查看更多詳細信息。
翻譯自: https://www.javacodegeeks.com/2015/03/intellij-idea-internal-design.html
intellij idea
總結
以上是生活随笔為你收集整理的intellij idea_IntelliJ IDEA内部设计的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: spring可用于数据层吗_Spring
- 下一篇: jcache_窥探JCache API(