2022.02.08 今天读了一篇关于前端整洁架构的设计,因此对其中的内容进行了一些整理以及我自己的思考,后续阅读《领域驱动设计》后可以加入更多的内容。
References:
架构方面学习笔记(3)–前端架构设计
整洁架构
以一个🌰来介绍整洁架构:
商店会出售不同种类的饼干,用户可以自己选择要购买的饼干,并通过三方支付服务进行付款。
用户可以在首页看到所有饼干,但是只有登录后才能购买,点击登录按钮可以跳转到登录页。
把饼干加进购物车后,用户就可以付款了。付款后,购物车会清空,并产生一个新的订单。
上图明确出了整洁架构的三个部分,但它还是有一些抽象,在实际开发和设计中我们如何遵循这个架构进行设计呢?
- 明确实体,比如例子中的:商品、用户、购物车、订单。明确数据转换函数(必须仅依赖本层的各种实体和规则)如计算总价的方法
- 应用层:
- 列 use case:①找出参与者②找出动作③明确结果
- 写数据转换或者说描述 use case:side effect(从适配层与服务端的交互中拿数据) --> pure function(纯函数处理数据)–> side effect(存储处理结果)
- 列 Interfaces - 适配层:
- 用户界面
- API 请求
- 存储或状态管理
最后:整洁架构让每个 use case 独立起来,同时适配层让第三方服务随时可替换,这会让整个架构扩展性极强,但不可避免的会带来一些如代码量的增大这种劣势。
我个人看法是整洁架构最关键的一点是希望逻辑和 UI、第三方服务 能够分离,而如今的 react vue 都提倡使用 hooks,核心也正是如此。在现实开发中实现理想状态下的整洁架构当然是具有一定的难度和不可预测性,比如你真的可以做到逻辑和状态管理的真正分离吗,你的项目可以随意从 react 和 vue 中切换吗,诸如此类的问题。但梳理整洁架构的过程仍然给了我们不少启发:
- 通过列实体、列 use case 对于我们设计 store 结构具有很大的帮助
- 将逻辑从状态管理、第三方服务中剥离出来,尽量做到各司其职和不依赖框架的测试
// 整洁架构下的商品购买代码树
src/
|_domain/
|_user.ts
|_product.ts
|_order.ts
|_cart.ts
|_application/
|_addToCart.ts
|_authenticate.ts
|_orderProducts.ts
|_ports.ts
|_services/
|_authAdapter.ts
|_notificationAdapter.ts
|_paymentAdapter.ts
|_storageAdapter.ts
|_api.ts
|_store.tsx
|_lib/
|_ui/
DDD(Design Driven Design) 领域驱动设计
Reference:
《领域驱动设计》
特点: 从开发到测试整个团队使用同一的架构语言;业务与架构强关联,从而建立针对业务变化的高响应力架构
几个名词解释:
DDD 中有较多的术语,这里仅写了几个,更多的可以参考 领域驱动设计-什么是领域驱动设计和怎么使用它
- 领域:一个系统要解决的实际问题的集合,或者说业务本身
- 通用语言:所谓通用语言讲的并不是开发和测试都用一种开发语言,比如 golang,JavaScript 等,而是与领域模型相关的结构化语言保证整个团队对整个系统的理解一致,比如一个商城系统中的订单收货地址和个人信息收货地址应该明确区分,而不是混为一谈「收货地址」
上文中提到的前端架构设计其实类似于 DDD 六边形架构。
DDD 相对于三层架构有什么提升?
三层架构的劣势:MVC 可以看做是三层架构的一种实现模式,我们知道任何一个操作都是从 controller 层传入,services 层操作数据库或者第三方服务。
- 严格分层模式下,用户界面层不能跨过业务逻辑层调用数据访问层
- 三层架构下往往 service 层会越来越臃肿,最终一堆逻辑混杂在一起,不易于扩展以及满足新的业务需求
三层架构又被称为「分层贫血领域模型架构」,贫血即指业务实体中没有或者很少方法。而 DDD 则被称为充血领域模型,正式因为领域对象拥有更多的能力。
待增加更详细的内容