模块化构建和微服务_模块规则可以保护您的构建时间和体系结构

模块化构建和微服务

问题 (The problem)

Modularisation is great and teams are highly encouraged to modularise their codebase. However with benefits of this comes a risk, that after the effort of modularising, new dependencies within modules slip in. Eventually we can realise that our modules graph is actually a list or we have a spaghetti modules graph, with more drawbacks than advantages.

模块化很棒,强烈建议团队对他们的代码库进行模块化。 但是,这样做带来的好处是,经过模块化的努力之后,模块中的新依赖项便潜入了内部。最终,我们可以意识到我们的模块图实际上是一个列表,或者我们有一个意大利面条模块图,弊大于利。

模块规则 (Module rules)

Many teams have agreed dependency rules and a recommended structure. At least orally, written somewhere in a better case. The problematic part is module dependency is so easy to add — single line in a Gradle file.

许多团队已经同意了依赖性规则和推荐的结构。 至少是口头的,写在更好的情况下。 有问题的部分是模块依赖性很容易添加-Gradle文件中的一行。

Murphy’s law of dependencies: Whatever they can access — they will access.

墨菲的依赖定律:无论他们可以访问什么,他们都将访问。

Once the dependency is in place, engineers often don’t even recognise that they start using classes from other modules. Android Studio is offering them, so why not? Any usage of class across modules tightens the screws. When the responsible engineer finally finds out, it is too late — one week of refactoring is a hard sell to your product manager.

一旦依赖关系到位,工程师通常甚至都不认识到他们开始使用其他模块中的类。 Android Studio提供了它们,为什么不呢? 任何在模块上使用的类都可以拧紧螺钉。 当负责的工程师最终找到答案时,已经为时已晚–重构一周对您的产品经理来说是很困难的。

In such situations, you regret not having the discussion at the moment the dependency was introduced. Perhaps just a small change or one interface would prevent the disaster.

在这种情况下,您很遗憾在引入依赖项时没有进行讨论。 也许只需很小的更改或一个接口就可以防止灾难。

建立时间影响 (Build time impact)

Modularisation can improve your build time especially if we achieve a flat structure of independent modules to leverage your machine’s multithreading capabilities. Ideal modules graph could look like this:

模块化可以缩短您的构建时间,尤其是当我们实现独立模块的扁平结构以利用您的计算机的多线程功能时。 理想模块图如下所示:

Build will take [3 + 15 + 2 seconds] 构建将花费[3 + 15 + 2秒]

The clean build of an application like this will take 20 seconds.

像这样的干净构建应用程序将花费20秒。

During some task, we suddenly realise we need config within analytics and also we need to use analytics in our users module.

在执行某些任务时,我们突然意识到我们需要 analytics config ,我们还需要在users模块中使用analytics

A quick solution unfortunately takes only 2 lines of Gradle configuration:

不幸的是,一种快速的解决方案仅需要两行Gradle配置:

api project('feature-config') // feature-analytics/build.gradle
api project('feature-analytics') // feature-users/build.gradle

and our optimised build time doubles to 40 seconds.

并且我们优化的构建时间翻了一番,达到40秒

We have lost 20 seconds on each clean build, affecting incremental builds as well by a bigger amount of tasks executed in a serial order. We don’t see this immediately — at the moment we realise, it might be too late.

我们在每个干净的构建上都损失了20秒的时间,这对增量构建也产生了影响,因为按顺序执行的任务数量更多。 我们不会立即看到这种情况-目前我们意识到,可能为时已晚。

Build will take [3 + 10 + 10 + 15 + 2 seconds] 构建将花费[3 + 10 + 10 + 15 + 2秒]

建筑影响 (Architecture impact)

The module graph above is most likely making you feel uncomfortable. We shouldn’t design applications like this.

上面的模块图很可能会让您感到不舒服。 我们不应该设计这样的应用程序。

We invest time into managing logical class layers and we also design our APIs to follow and reinforce these hierarchies. Similarly, we need to apply some sort of reinforcement to keep our module graph in a good shape. Otherwise, its bad shape can have the same consequences like spaghetti code.

我们投入时间来管理逻辑类层,我们还设计了API以遵循和加强这些层次结构。 同样,我们需要应用某种形式的增强来使模块图保持良好的形状。 否则,其形状不好可能会产生与意大利面条代码相同的后果。

执行规则 (Enforce the rules)

Gradle provides an API to browse dependencies and we can access these through project.configurations property. Through these properties we can inspect for example api or implementation dependencies. Example of getting all dependencies of single module:

Gradle提供了一个浏览依赖项的API,我们可以通过project. configurations来访问它们project. configurations project. configurations 属性。 通过这些属性,我们可以检查例如apiimplementation依赖性。 获取单个模块的所有依赖项的示例:

One way of enforcement can be a Gradle plugin, browsing dependent modules and in case of any violation, notify the engineer or even more aggressively — fail the build.

一种执行方式可以是Gradle插件 ,浏览依赖的模块,并在发生任何违规情况时通知工程师,或者甚至更加主动地-编译失败。

Module Graph Assert plugin implements this technique and provides an assertion system for your project modules based on regex matching. You can define layer hierarchy, maximum height of the graph or your custom restrictions.

Module Graph Assert插件实现了此技术,并基于正则表达式匹配为项目模块提供了一个断言系统。 您可以定义图层层次结构,图形的最大高度或自定义限制。

The plugin will add a new task assertModuleGraph to the check task, quickly verifying these rules and failing in case any are violated. This should trigger the right conversations in the right moment when your desired module structure is in danger.

该插件将向检查任务添加新任务assertModuleGraph以快速验证这些规则,并在违反任何规则时失败。 当所需的模块结构处于危险中时,这应该在正确的时间触发正确的对话。

You can also generate your modules graph by Graphviz to get more insights where you can improve your modules structure.

您还可以通过Graphviz 生成模块图 ,以获得更多可改进模块结构的见解。

享受模块化世界 (Enjoy the modular world)

Modularisation is powerful and if done right, it will bring you many benefits. Unfortunately, if done wrong it can bring you harm, frustration and rework.

模块化功能强大,如果操作正确,它将为您带来许多好处。 不幸的是,如果做错了,可能会给您带来伤害,沮丧和返工。

Agreeing with your team on how your modules graph should look like is a first step. However only agreed rules might not be enough: reinforce your decisions by enforcement.

与您的团队就模块图的外观达成共识是第一步。 但是,仅商定的规则可能还不够: 通过强制执行来加强您的决策。

How big is your module graph? Any insights to share? You are welcome to post your modules graph or thoughts in comments.

您的模块图有多大? 有什么见解可以分享吗? 欢迎您在评论中发布模块图或想法。

Happy coding!

编码愉快!

翻译自: https://proandroiddev.com/module-rules-protect-your-build-time-and-architecture-d1194c7cc6bc

模块化构建和微服务

你可能感兴趣的:(python,java,人工智能,vue,大数据,ViewUI)