由于技术的进步,现代企业应用无需从头开始开发,而可以利用企业应用平台,通过组件化、低代码乃至无代码的方式来构建,以获得更高的质量、性能和交付速度。本文提出企业应用平台的一种以元数据为中心的、基于六大引擎的架构。平台以元数据和业务领域为中心,六大引擎环绕着中心,为企业应用的开发提供强大的赋能。
有人可能会质疑低代码开发模式,而我认为这主要是由于低代码开发还没有得到现代软件工程的赋能,所以不够好用,因此未来的一个重要战略方向就是用现代软件工程来赋能低代码开发,即低代码软件工程(以后可以探讨这一话题)。
每一个引擎都是一个产品,可以由一个团队来负责开发和维护。可以基于开源产品做二次开发,但是一定要完全掌握每一个引擎,才能确保平台的整体的高质量。
这六大引擎是:
- 数据引擎:负责数据的建模、管理和存取,为其他引擎提供数据源。换言之,是对数据库的一种高层封装机制。它比较像Martin Fowler所述三层架构中的数据源层,或者DDD(领域驱动设计)中的Repository概念,但是有所不同。这是最重要的一个引擎,因为可以说企业应用都是面向数据的,是围绕数据而建的。数据引擎要支持对象关系映射,要能自动管理DB schema(例如自动建表)。最好还能够内置软删除、草稿、审计等功能,这几样功能适合统一建设,不需要让上层应用进行重复建设。数据引擎的底层是ORM框架,市面上没有合适的数据引擎产品(Supabase勉强算一个)或ORM框架(JPA勉强算一个),建议全新开发。您可能会问,它与ORM框架有什么区别呢?最主要的区别为,数据引擎支持低代码开发模式,甚至能实时创建和修改数据模型而无需重启服务器。
- 表现引擎:负责各种数据交换的建模、管理和执行,例如为数据类型自动导出CRUD API、将数据记录转换成适合UI显示的VO(视图对象)或适合API使用的DTO(数据传输对象)。这个引擎也相当重要,后文会介绍它为什么如此重要。市面上没有合适的表现引擎产品,需要全新开发。
- 安全引擎:负责安全策略的建模、管理和执行,其中一项比较显著的功能是对数据访问权限的管理。对于重视安全和权限的企业应用,安全引擎是很重要的。市面上没有合适的安全引擎产品,需要全新开发。
- 规则引擎:负责业务规则的建模、管理和执行,业务规则可以用规则语言或图形化编辑的方式来编写,可以在运行时动态更新。规则引擎不是必要的(您也可以在系统代码中硬编码所有的业务规则),但是很实用,它让业务规则能被更简单更快速地交付。市面上有一些开源规则引擎如Drools,也有一些脚本引擎如Groovy、AviatorScript、MVEL等可以被当作简易的规则引擎来用。以上这些产品都需要用户手动用脚本代码的形式来编写规则。还有一些商业规则引擎支持低代码的可视化开发。这些引擎产品不支持元数据,所以要么将它们经过二次开发再使用,要么开发全新的引擎产品。由于脚本引擎产品大多有较高的内聚性和成熟度,可以当成一个程序库来用,建议采用二次开发的方式。
- 流程引擎:负责业务流程的建模、管理和执行,业务流程可以用流程语言或图形化编辑的方式来编写,可以在运行时动态更新。流程引擎不是必要的(您也可以在系统代码中硬编码所有的业务流程),但是很实用,它让业务流程能被更简单更快速地交付。流程引擎一般都支持低代码的可视化开发。市面上的开源流程引擎有jBPM、Activiti、Flowable等,它们都基于一种名为BPMN的流程定义语言规范,也有一些流程引擎如Temporal、Step Functions、Apache DolphinScheduler不基于BPMN规范。这些引擎产品不支持元数据,所以要么将它们经过二次开发再使用,要么开发全新的引擎产品。由于BPMN系流程引擎产品大多复杂臃肿,可扩展性差,因此我们建议基于非BPMN系产品做二次开发或者直接全新开发。
- 智能引擎:负责各种智能(报表、商业智能和人工智能)的建模、管理和执行。在如今的智能时代,几乎没有企业会放弃建设智能系统,智能引擎的重要性不言而喻。智能是一个前沿领域,还需要更多探索。
为什么以元数据为中心?
一个架构至少需要一种能在其内部通用的数据交换格式,例如因特网是基于包(packet)的。元数据就是这么一种格式,它是各个引擎之间的主要沟通桥梁,也是低代码开发的核心要件。元数据可以被表示为JSON或YAML格式的配置数据,它是在数据之上的对于数据结构和语义的描述信息。开发者在构建企业应用时,一般会使用SQL DDL创建一些数据库的表(database tables),并且编写一些实体类(entity classes)的定义代码(例如用Java来编写)。您可以大致认为,元数据对应的就是实体类(实际上元数据可以包含实体模型、视图模型、权限模型等多种信息)。
请想象一个典型的低代码开发过程:
- 有一款在线可视化编辑器,允许您在GUI上即时创建一个实体类。您可以创建一个User类,给它添加一些字段(例如name, country, age),然后一保存,这个实体类就在系统中生效了(现在你可以存储和查询User类的数据记录了),无需手动编写实体类代码。这个编辑器所保存的信息就是元数据,它记录了这个实体类的结构定义。以上功能是利用数据引擎实现的。
- 进一步,您还可以在线创建一个视图,它基于刚才那个实体类(User),但是只包含一些想展现的字段(name, country),排除了某些不想展现的字段(age),并且可以附带某些过滤条件表达式(country=currentUser.country),即通过这个视图只能查询到那些与当前用户属于同一个国家的用户。以上功能是利用表现引擎实现的。
- 您可以直接在代码中访问这个视图,也可以为这个视图自动导出一个Web API。您也可以创建一个角色(Role),把视图绑定到此角色,再把角色授予某些用户,那么这些用户在访问User信息时就只能看见这个视图,而不能看见原始的User类。这样一来,用户就只能看见允许被授权给他们的数据,而不能看见全量数据。以上功能是利用安全引擎实现的。
- 您可以创建一个业务规则,将触发时机设在User类的数据被删除之后(afterDelete),此规则会查找即将被删除的这个User所拥有的资产数据,将这些资产数据标记为冻结状态。以上功能是利用规则引擎实现的。
- 您可以创建一个业务流程,将触发时机设在User类的数据被删除之前,此流程会发起一个审批流程,只有完成了审批流程,才会执行删除操作。以上功能是利用流程引擎实现的。
您可以创建一个有用的视图并把它自动导出为一个报表。您也可以编写一些代码,通过对元数据做一些操作来生成报表。以上功能是对智能引擎的简单利用。如今大数据领域也在强调“元数据管理”(例如Apache Atlas),这与我们的目标其实是一致的,将企业应用平台的元数据与大数据平台的元数据连通,是对元数据的一种很好的利用方式。
为什么是基于引擎的架构?
依据康威定律,系统的架构实际上是由组织的沟通结构所决定的。提出引擎这一抽象,就是为了让企业应用平台的架构适应一般组织的沟通结构。每个引擎都是一个内聚的领域,可以由专门的团队来负责。元数据作为各个引擎之间的主要沟通桥梁,引擎之间也可以通过引擎的API沟通,上层应用则和元数据和各个引擎的API沟通。
其实一些企业应用平台已有向这种架构风格发展的趋势,本文只是推动它的正式化。为什么是六个?
本文只提出了最重要的六大引擎,这是一个巧合的数字,但您也可以认为它与六边形架构(hexagonal architecture)是有所呼应的。除此六大引擎,当然还可以有其他引擎,但其重要性相对较低。我们只关注这六大引擎,而它们的组合足以用于构建大多数的企业应用。
可以采用微服务架构吗?
这是一个值得回答的问题。回答是:可以,但有所限制。基于平台的业务应用当然可以用微服务架构来建设,但这个平台本身并不适合微服务架构。如果您想将每个引擎做成一个微服务,不建议这么做。引擎之间的联系比较紧密而且细粒度,每个引擎一个微服务的方式不利于性能和可靠性,我见过一些失败的引擎微服务架构尝试。
推荐的总体架构是,每个业务应用被部署为一个服务,在每个服务中同时部署了所有的引擎。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。