原文链接: Clean Frontend Architecture - 原文作者: Robert Maier-Silldorff
本文采用的是意译的方式
这个话题将涉及到很多的原则:
SOLID, KISS(Keep It Short and Simple), DRY(Don't Repeat Yourself), DDD(Domain-Driven-Design) 等等
我们为什么需要前端架构?
功能性和非功能性需求不仅需要应用到后端,也需要应用于前端。因此,前端架构能够满足商业的需求。而且,我们可以更好理解项目的复杂性,从而减少项目的风险、时间和成本。然而,在我看来,前端架构最有价值的原因是任何项目的可维护性和可扩展性。
前端架构应该是什么样子的?
根据我的经验,大多数情况下,Layered Architecture(分层架构)
被使用到。然而,我必须承认我也遇到过一些应用了 Hexagonal Architecture(六边形架构)
的项目。
下图,是一个简单的旅行社项目为例子说明。
哪层被用到?
- API:通过
Open-API
生成器生成DTOs
和Services
- Service:包含
Mappers
(DTO
和 前端模型相互转换),使用REST
对API
进行通信服务 - Store:存储从
Service
层获取的数据 - Booking:包括模型
Models
和组件Components
的区域。
DTO - Data Transfer Object,即数据传输对象
这种架构会出现哪些问题?
嗯~如果没有定义规则,那么开发者可能会在他们的组件直接使用 DTOs
或者与服务层进行通信而不使用存储层。或者说糟糕的是,组件直接与服务层通信,这是多愚蠢。
我们怎么预防这些错误呢?
预防这事情的发生,我们简单定义一些规则。其中最常见的方法之一是在项目中引入 Bit
或者 Nx
。那么,Bit
是什么?Nx
又是什么?
Bit 和 Nx 是很强大的开源系统,提供了增强开发者生产力、优化持续集成性能和保持代码质量的工具。
所以,Bit
和 Nx
二选其一应用。因此,在使用错误的层时,开发者会被提示错误。
那是很有效的方法,但是我们怎么确保领域 Domain
自身(例如上面订阅领域)保持可维护呢?
我们可以应用一些 DDD(Domain Driven Design)
概念到我们的 Booking Domain
。因此,我们将 Booking Domain
切分为多个子领域 Sub-Domains
。每个子领域有自己的边界上下文和共享语言。正如下图所示。
每一个子领域都是用分层架构,然后通过子领域的 APIs
相互通信。特性 Feature
包括智能的组件和服务,UI
包括亚组件, Domain
包括模型,而 Util
包括这个边界上下文中使用的实用函数。
现在,一定程度上我们有了清晰的架构,不是吗?我们已经很接近(成功了),但是还是没到那里。拥有一个架构不够,底层组件和和业务逻辑必须使用 Clean Code principle
干净代码原则。因此,让我们深入探讨 Feature
和 UI
层。
哪些原则应该被使用到组件上?
首先,也是最重要的该属 SOLID
原则。每个组件必须是单一原则(Single Responsibility Principle
)。使用组合而非继承,开放封闭原则(Open-Closed Principle
)。不要强制组件实现不适合它的接口,意思是并非所有的方法都有意义,接口隔离原则(Interface Segregation
)。还有要记住的是,组件不应该直接依赖低级别的服务,依赖反转(Dependency inversion
)。
SOLID
中还有一个原则 -> 里氏替换原则(Liskov Substitution Principle
):子类应该能够替换掉父类而不导致程序的错误行为。
第二,当将业务逻辑应用到组件 Component
,服务 Service
或者工具 Util
时,我们应该记住 KISS (Keep it short and simple)
原则。为什么我们要这么做?因为越简单的代码越好维护。
第三,尽量避免重复的代码(DRY, 即 Don't repeat yourself 原则
)。将公共的业务逻辑移动到 Utils
或者 Services
中。