当前位置: 首页 > 科技观察

为什么说应用架构需要分类思维呢?_0

时间:2023-03-13 21:32:37 科技观察

如何定义建筑?应用程序架构的元素是什么?应用架构中的分类思想是什么?开源应用架构COLA作者张建飞介绍了他在COLA架构设计上的一些思考和经验,并分享了他的应用架构。模块(Module)、组件(Component)、包(Package),这些概念对于我们技术同学来说并不陌生,但并不是每个人都能理解它们的本质。深入理解后,我发现其背后的深层含义是分类思维。而这种分类也是应用架构的核心。通过不同粒度、不同层次的划分,可以将复杂软件系统的实现控制在可理解和可维护的范围内。否则,人类没有办法理解和维护代码量为100万行的软件。想象一个极端的情况。如果没有这些概念来帮助我们分类,如果我们把所有的业务逻辑都写在一个类中会怎样?我们很多“非人类”的系统正是因为缺乏合理的分类造成的。早期,我不喜欢JavaScript的一个重要原因正是因为它缺少Java中的package和jar的概念,导致代码组织松散、随意。直到ES6和React才解决了这个问题。在此之前,前端工程师不得不依赖seaJS、requireJS等框架来做模块化、组件化的事情。说到这里,你可能会有疑问,分类有什么神奇之处?它是如何成为应用程序架构的核心的?别担心,让我详细解释一下。分类的重要性所谓分类,就是把给定的事物按照一定的标准进行分组。我们人类天生就有分类的本能,例如,当我们看下图时。任何人第一眼看到这六个黑点都会以为是两组三个墨点。这种印象主要是由于这样一个事实,即人脑会以某种连续性自动组织它发现的一切。基本上,大脑假设同时发生的任何事情都以某种方式相互关联,并将这些事情组织成某种逻辑模式。我们的大脑之所以有这种本能,是因为人类一次可以理解的思想或概念的数量是有限的。正如GeorgeMiller在他的论文《奇妙的数字7》中提出的那样。人脑的短期记忆一次不能容纳超过7个记忆项目。因此,当信息量过大时,只有分类分组才能帮助我们理解和处理问题。其实,人类从古至今都在进行分类/归类。早在春秋战国时期,《战国策》就提出了“物以类聚,人以群分”的观念。在互联网行业,我们对客户进行分类,然后针对不同的客户进行分级操作,也是这个道理。我们通常所说的分析和综合的背后其实是分类的能力。分析是在一类中寻找差异,综合是寻找不同事物之间的联系和共性,而这种共性就相当于分类的维度。分类思维的能力直接体现了看透事物本质的能力。应用架构中分类思维概念定义在讨论架构之前,我们先明确一下Module、Component、Package的概念。因为这些概念一直有很多歧义。这可以从StackOverflow上关于这些概念差异的数十个问题以及不同的回答中看出。在StackOverflow帖子[1]中,我们看到了这个答案:术语相似。我通常认为“模块”比“组件”大。组件是单个部分,通常范围相对较小,可能是通用的。然而,另一篇StackOverflow帖子[2]给出了不同的答案:没有衡量哪个比另一个更大的标准。一个组件可以包含模块列表,一个模块也可以包含多个组件。在《实现领域驱动设计》一书中,作者有这样的描述:如果你正在使用Java或C#,你已经熟悉了Modules,尽管你知道它们的另一个名字。Java称它们为包。C#称它们为命名空间。但是在AngularJS的设计文档[3]中,是这样定义Module和Component的:模块可以看作是组件的集合,每个组件都可以使用其他组件。许多模块之一组合起来制作一个应用程序。通过对比,结合自己的认知,我比较认同AngularJS中的定义,即Module是一个比Component更大的概念。比如在Maven中,Module是第一级应用,Component的粒度一般比Module小,多个Component会组成一个Module。因此,在进一步讨论之前,我特意将这些概念定义如下:Application:应用系统,由多个模块组成,用一个方框表示。Module(模块):一个Module由一组Component组成,用一个立方体表示。组件:表示能够独立提供一定功能的对象,用UML组件图表示。包(Package):包是比较靠谱的。它是一种组织形式,而不是粒度的维度。也就是说,一个Component可以包含多个Package,一个Package也可以包含多个Component。基于以上定义,他们的表示法如下:应用程序架构的元素架构的定义有很多,我最喜欢也是最简洁的定义是:即架构是由对象(Components)+对象之间的关系+指导原则。应用程序架构也是如此。从大的角度来看,企业级应用都逃不开下图所示的三层结构,即前端、后端、数据库。对于后端开发来说,应用层是我们的主战场,也是整个系统中最复杂的部分(当然前端也不简单),所有的业务逻辑都在这里汇聚。所以,对于应用层,我们需要进一步拆分,不能只在这里写业务逻辑。应用层的进一步分层形成了COLA所提倡的四层结构。对应Maven有4个Module,编译打包后会有4个Jars。一个典型的应用,它的Module呈现如下结构:->cloudstore-domaincloudstore-infrastructurecloudstore-clientstart当业务变得复杂时,这种分层结构自然比不分层要好。这也是COLA一直在努力解决的问题——控制复杂度。从COLA1.0的细节到COLA3.0的简化。我渐渐明白,COLA作为应用架构的核心不是提供功能,而是提供原型。在1.0时,COLA提供了Interceptor能力、EventBus能力和扩展点能力。一是觉得大家“需要”这些,二是觉得NB的框架应该是包罗万象的,没几个高级功能就不好意思开源了。事实证明,我犯了一个习惯性错误——过度工程化。拦截器完全可以被AOP替代,很少使用内部事件和扩展点。所以在COLA3.0中,果断去掉了这些“鸡肋”,只保留了扩展点功能。回到架构的本质,COLA的核心应该是规定应用的结构和规范,即应用架构原型(Archetype)。而不是纠结于那些锦上添花的功能。升级到COLA3.1事实上,COLA3.0几乎已经完成了这样的回归工作。在本次3.1升级中,除了进一步去除了EventBus的功能外,最重要的是重新规范了分包策略,扩大了原有控制层(Controller)的职责。分包策略调整分层是功能维度上的一种横向分割,即每一层都有自己的职责。适配层:路由用户请求+适配响应。App层:接收请求,与领域层一起做业务处理。领域层:领域模型+领域能力。基础设施层:技术细节(DB、Search、RPC..)+反腐败(Anti-corruption)。分层处理没有问题,但是这种功能划分会带来一个问题,就是领域维度的内聚性会受到影响。当一个应用程序只负责一个域时没有问题。但是,当一个应用程序包含多个业务域时,这种缺乏内聚性的缺点就变得更加明显。更好的分包策略是按领域而不是按功能。因为领域更有凝聚力,功能服务于领域,应该属于领域。然而遗憾的是,在COLA应用架构中,我们需要将水平功能维度的划分和垂直领域维度的划分结合起来。两者都很好,我们都想要。该怎么办?我们可以结合使用物理划分和逻辑划分。横向上,我们使用Modules进行层级划分,属于物理划分。纵向上按Package逻辑划分。最后形成如下结构:按照这个思路分包。在项目中,Module下的顶层包不再是一个功能,而是一个领域:按照领域分包策略至少会带来两个好处:理解性和可维护性更好。大白话,找东西比较容易。方便以后拆分。比如订单域(Order)越来越复杂,需要拆分。我们只需要将Order下的东西迁移到一个新的应用中即可。Adatper代替ControllerController的名字主要来源于MVC,因为是MVC,所以有Web应用的烙印。但是随着移动端的兴起,只支持Web端的应用已经很少了。通常的标准配置是Web、Mobile、WAP三端都支持。在这种背景下,狭窄的控制层已经不能满足需求,因为在这一层,不仅需要路由转发,还需要多端适配,类似于六边形架构中DrivingAdapter的作用。鉴于此,我们将Controller换成了Adapter。一方面是呼应六边形建筑;另一方面,确实需要做多端适配。基于这些变化,我重构了COLAArchetype,将Adapter突出显示为一个层。Infrastructure其实也是一个适配器,是技术实现的适配(或者解耦)。比如我需要数据来帮助构造DomainEntity,但是我不关心数据是来自DB、RPC还是Search,或者说,我可以在这些技术实现之间自由切换,而不会影响我Domain层的稳定性和应用层。修改后的COLA将在架构风格、模块、组件、分包策略等方面进行调整。具体改动可以参考下面两张图。COLA架构图:COLA3.1COLA组件关系图:更多关于COLA3.1.0的信息可以访问:https://github.com/alibaba/COLA。分类思维这种重要的思维能力在组织结构中的应用绝不仅限于架构设计的范围。正如开头所说,分类是我们人类的本能,是分析和综合问题的重要手段。生产关系决定生产力,好的组织架构有利于企业发展,反之则阻碍企业发展。所以大公司的老总每年都会花很多时间在组织设计上,这就是为什么在大厂里,我们每年都会看到很多的组织调整。看到一篇文章《苹果公司的组织架构是怎样的》[4],介绍了苹果公司的成功与其优秀的组织结构有关。如下图所示,传统企业更倾向于业务型组织,而高科技企业更倾向于功能型组织。是不是觉得苹果的组织结构和我们COLA的idea是一样的:),物理上,是按职能划分的;从逻辑上讲,它是按业务和产品划分的。Apple的组织设计是因为它是一家以技术和创新为驱动力的公司。合作的成本并不是最大的问题。缺乏专业性(不是好的技术)和缺乏创新是生死攸关的大问题。所以,他宁愿牺牲协同效率,也要保证专业性。也就是说,做相机的只做相机,做iOS的只做iOS。技术负责人直接向CEO汇报,可以决定产品开发的方向。因为他们在这个领域更专业。很久以前,史蒂夫·乔布斯(SteveJobs)就指出苹果公司的经理应该是各自领域的专家。在1984年的一次采访中,他说:我们在苹果公司经历了那个阶段,当时我们想,哦,我们要成为一家大公司,让我们聘请职业经理人。我们出去聘请了一批职业经理人。它根本不起作用……他们知道如何管理,但他们对专业知识一无所知。如果你是一个伟大的人,你为什么要为一个你无法从中学到任何东西的人工作?你知道有什么好玩的吗?你知道谁是最好的管理者吗?他们是伟大的个人贡献者,他们从不想成为一名经理,但决定我必须这样做,因为没有其他人能很好地完成这项工作。说实话,看完这篇文章,我很感动。一方面,我佩服乔布斯的洞察力,另一方面,我也为我们这个行业感到惋惜。业务技术也是技术,但是没有像样的环境和环境来培育和发展技术。土壤。今天,有多少业务技术领导者仍然专注于技术,仿佛他们都成为了业务领导者。如果技术领导变成纯粹的管理者,那么谁关心技术,谁关心代码,谁关心工程师的成长?分类学既是科学又是艺术。难度也很大,具有一定的主观性。正如BillBryson在《万物简史》中所说:分类学有时被描述为一门科学,有时被描述为一门艺术,但实际上它是一个战场。即使在今天,该系统也比许多人想象的还要混乱。以描述生物基本结构的门的划分为例。许多生物学家坚持总共有30个门,但也有人认为有20个左右的门,而爱德华在他的书《生命的多样性》中提出了惊人的89个门。我们观察事物的角度不同,对问题的认知层次不同,所以得到的分类也会不同。以COLA为例,直到现在的3.1版本,我个人认为它的分层分包方式还是比较合理的。但是很有可能在后面的迭代中,分类方式又会发生变化。组织结构的分类也是如此,可以按照业务和职能来划分。关键是看它的分类是否符合你单位的特点。没有最好的分类,只有最合适的。除了本文分享的分类思维,更多的思维技巧也可以在作者的新书:《代码精进之路:从码农到工匠》中找到。这是一本写给专业程序员的书。主要分为技能、思路和实践三个部分。详细介绍了编程技巧和方法、抽象能力、分而治之的思想、常见的应用架构模式,以及COLA架构的原理。设计原则。希望能帮助程序员养成良好的编程习惯和思维。相关链接[1]https://softwareengineering.stackexchange.com/questions/178927/is-there-a-difference-between-a-component-and-a-module[2]https://stackoverflow.com/questions/2702816/module-vs-component-design[3]https://medium.com/swlh/angular-component-vs-module-b8c7347c604e[4]http://www.techweb.com.cn/cloud/2020-10-27/2808376.shtml【本文为《阿里巴巴官方技术》专栏作者原创稿件,转载请联系原作者】点此查看该作者更多好文