架构守卫的编码,即使用易于阅读和维护的领域特定语言来描述软件架构守卫的规则,例如分层架构、包访问规则、包数量、继承命名等。受限制的。PS:我们这里所说的编码,指的是用特定领域的语言来描述。早前,我只是因为用Java写的ArchUnit不支持其他语言,在其他语言的生态中,也没有这样合适的工具。于是,我想到了在Uncode中设计一个全新的架构守卫工具,就是Inherd开源组中的Guarding:https://github.com/inherd/guarding/,一个多语言的架构守卫工具——基于TreeSitter解析各种编程语言。它设计了一个外部DSL,借用了ArchUnit设计的内部DSL的语法。架构腐败:为什么我们需要架构守卫?在开发过程中观察软件架构的变化是非常有趣的。日常经常和大中型公司的架构师和技术负责人聊天,讨论一些架构和规范相关的问题,也是蛮有意思的。我们讲架构的时候,从聊天过程来看,还是挺漂亮的。但是,当我们打开代码库,看到代码的分层实现和代码的一些规范时,就会发现结果并不是这样的。好的开始。在系统设计的初始阶段,架构师们根据自己的能力和经验,对系统进行了快速而“细致”的设计。然后在迭代开发中,根据自己新掌握的知识,对系统进行一些调整。如果这些资深架构师在编码(断断续续),或者经常打开代码库看一看。那么,系统自然不会偏离太多。所以,我坚信对于一定规模的软件组织来说,他们对于系统是有好的设计的。损坏的架构。在系统的中后期开发过程中,之前的架构师对架构的关注度不够,或者经历了一些人事变动,导致系统的架构相继出现不一致的情况。当然,架构相关的文档和规范的缺乏维护也是一个典型的原因。由于这一系列的种种原因,我们看到的系统架构与这些架构师最初的预期并不一致。基于以上原因,在架构上实施守卫成为了很多架构师不得不考虑的问题。为什么需要对架构进行编码来守卫?程序员讨论写文档,恨别人不写文档。建筑知识的记录、传播和转化也属于知识传递的范畴。从现阶段来看,有以下不同层次:系统本身没有架构文档,文档存在于人们的脑海中。系统有架构文档,很难看懂(没有架构图)。系统存在体系结构文档,仅在早期创建,但与实际体系结构不一致。系统架构文档不断更新,但未能及时响应问题。系统的架构文档不断更新,并使用架构守卫来保证两者的一致性。系统的架构文档是系统的架构守卫测试。以上几点,我想无论是开发者还是架构师,都深有体会。需要阅读并记住记录的体系结构。在架构设计的早期阶段,开发者经常会经历关于架构设计的刺激性讨论。所以,大家对建筑的造型都有很好的把握,不需要太多记录也能知道设计。沉淀式文案往往只是一些决策的结果,缺乏程序性的讨论等。基于这些原因,在过去的几年里,我们一直提倡“架构决策记录”(ADR),记录与每个架构上下文相关的信息,决定,结果。架构测试的局限性是一个老生常谈的问题,所以在Java的世界里,人们设计了ArchUnit这样的工具来守护系统的架构。架构测试作为架构的文档,缺乏易读性等问题。它还需要大量复制和粘贴才能跨多个项目使用。PS:早期我也尝试过为JavaScript/TypeScript世界设计一个类似的架构守卫工具(即dilay),但是前端世界并没有迫切需要这个类。多年后,我设计了一个新的工具,只是它已经适配了多种语言和框架。Architectureguardiscode:Architecturedocument是测试架构守卫的代码,是用易于阅读和维护的领域特定语言来描述软件架构守卫的规则,如层次结构、包访问规则、数量包、继承命名等限制。ArchitectureGuardDSLExample一个好的架构文档就是一个测试,它是可以执行的。比如ArchUnit设计的内部DSL语法:classes().that().haveSimpleNameStartingWith("Foo").should().resideInAPackage("com.foo")描述了一个规则:以Foo开头的类应该放在下面com.foo包。这也是我们在设计架构时要设计的架构文档。如果我们将它翻译成英文,它将是:class(startsWith"Foo"))resideIn"com.foo"另一种可能的形式可能是:(startsWith"Foo").classresideIn"com.foo"来自实施难度,两者区别不大,但显然前者更容易理解和编写。以此类推,我们可以继续设计一系列的规则。其他欢迎加入InherdGuarding架构测试和守护。GitHub:https://github.com/inherd/guarding。本文转载自微信公众号「phodal」,可关注下方二维码。转载本文请联系phodal公众号。
