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内部设计相关推荐

  1. 解析IntelliJ IDEA内部设计

    IntelliJ IDEA第一版发布于2001年1月,这是第一款集成了高级代码导航和代码重构功能的Java IDE. 2009年,JetBrains开源了其社区版.从那时开始,就新出现了许多基于其社区 ...

  2. IntelliJ IDEA内部设计

    IntelliJ IDEA的第一版于2001年1月发布,当时它是第一个集成了高级代码导航和代码重构功能的Java IDE之一. 2009年,JetBrains开源了其社区版本 . 从那时起,创建了许多 ...

  3. vcm驱动芯片原理_T6322A|电源芯片的内部设计是怎样的?

    很多工程师每天都跟芯片打交道,却不了解芯片的内部结构是什么样的,导致芯片出了问题不能准确地判断,这是基础知识不够完备的表现.下面就来讲讲电源芯片的内部设计是怎样的. 一.电源芯片的各个功能是怎么实现的 ...

  4. 安卓收藏功能怎么实现_从电源芯片的内部设计,看各个功能是怎么实现的

    作为一名电源研发工程师,自然经常与各种芯片打交道,可能有的工程师对芯片的内部并不是很了解,不少同学在应用新的芯片时直接翻到Datasheet的应用页面,按照推荐设计搭建外围完事.如此一来即使应用没有问 ...

  5. 一颗芯片的内部设计原理和结构

    关注.星标公众号,直达精彩内容 来源:网络素材 摘要 作为一名电源研发工程师,自然经常与各种芯片打交道,可能有的工程师对芯片的内部并不是很了解,不少同学在应用新的芯片时直接翻到Datasheet的应用 ...

  6. 三星w2014android,三星W2014评测:机身细节及内部设计

    更多细节 作为三星最顶级的商务手机,三星W2014的做工拥有不错的表现,下面从转轴.卡槽.键盘和机身内部了解下. 三星W2014机身的插槽较多,SIM卡和扩展卡插槽都被设置在翻盖这半部分.与W2013 ...

  7. FastRTSP 内部设计

    进程间共享内存模型 概述 本文档描述了用于交换数据消息的软件组件的进程间共享内存通信的模型.该模型的目标是提供适用于实时发布-订阅 DDS(数据分发服务)的基于共享内存的传输层. 语境 eProsim ...

  8. Mxnet - Understanding weight shape for Dense Layer MXNET权重参数形状的疑惑(内部设计形式行列谁在前不用管,多个转置运算而已)

    Mxnet - Understanding weight shape for Dense Layer  MXNET https://stackoverflow.com/questions/474778 ...

  9. 干货| 生鲜电商的冷库内部该怎么设计(含案例)

    导语 大家好,我是智能仓储物流技术研习社的社长,老K.冷链物流工程庞大,生鲜食品的时效性向冷链物流的各个环节提出了更高的要求.如何设计出有针对性的自动化仓储物流系统呢? 文丨湖南涉外经济学院 刘红梅. ...

最新文章

  1. 试用 smartdraw 2010 方便快捷的图表工具
  2. legend3---lavarel常用artisan命令操作
  3. C++:读写二进制文件到double数组
  4. remoteing2
  5. Sqlite - constraint failed[0x1555]: UNIQUE constraint failed
  6. CAD填充技巧:填充图案
  7. amd linux raid,请问AMD RAID驱动怎么用
  8. JS-记事本(代码)
  9. 三年程序员成功转型项目经理
  10. 阿里云ECS服务器实例是什么意思?关于实例的讲解
  11. 假设检验之单个总体均值检验(含Python代码)
  12. 专访智齿科技徐懿丨企服公司四要素:智能、融合、产品复杂度、客单价
  13. 统计系列(二)常见的概率分布
  14. matlab运行LCT跟踪算法代码
  15. Loaders 的使用,结合Fragments
  16. SpringCloud之消息总线组件及微服务网关
  17. 最大网络流算法之dinic算法
  18. 小鸡小猪大历险java_奇想国大师名著:小鸡大冒险
  19. JAVA野人_修道野人 用谓词表示法表示修道士和野人的问题 在河的左岸有三个修道士 联合开发网 - pudn.com...
  20. ChatGPT - 使用28原则快速学习的Prompt

热门文章

  1. P3527-[POI2011]MET-Meteors【整体二分,树状数组】
  2. jzoj3896-战争游戏【tarjan,割点,点双联通分量】
  3. jzoj2700-数字【数论,LCM】
  4. jzoj1295-设计【差分约束系统,最短路】
  5. 【LCT】洞穴勘测(luogu 2147/金牌导航 LCT-1)
  6. IQ测试(jzoj 5048)
  7. 纪中培训总结(2019年9月4~13日)
  8. Sentinel(七)之网关限流
  9. mybatis源码阅读(二):mybatis初始化上
  10. MySQL year()函数