随着我们解决的场景越来越专业化和复杂化,大型SPA应用的流行,前端承担的职责越来越多。很容易导致迭代着迭代着发现代码改不动了。最后只能新起炉灶,重新开发。归根到底在于 复杂度的失控
,此时就需要一些理念来指导开发。
背景:
为什么迭代越来越难?原因在于:
-
问题域本身错综复杂
- 软件本身是为了管理复杂度,我们现在面对的问题域错综复杂。为了创建真正好用的软件,开发者必须有一整套与之相关的知识体系
-
技术模型与领域模型不匹配
- 一般我们很容易抽象出一个独立的类、函数来放通用逻辑,这个通用类、函数只有技术维度上的通用。技术维度上的通用
很容易被业务摧毁
。需求上的变动或者膨胀,技术维度的通用很容易被摧毁。根本原因就是我们设计的技术模型
与领域模型
不匹配。于是每次需求的改动,映射到技术模型的改动可能就是极大的工作量。甚至根本改不动,在业务压力很大的时候,我们只能告诉产品经理,这个可以做,但是我们需要2个月。结局很可能就是需求方的妥协,牺牲用户的利益。导致产品越来越难用。
- 一般我们很容易抽象出一个独立的类、函数来放通用逻辑,这个通用类、函数只有技术维度上的通用。技术维度上的通用
-
知识的丢失
- 任何项目都会丢失知识,外包出去的系统可能只交回了代码,知识没有传递回来。离职了,转岗了,一旦出于某种原因人们没有口头传递知识,知识就丢失了。
上这三个问题归根到底,就是我们没有在前端代码里把我们业务描述清楚。我们很多情况下是 视图驱动
,而不是 业务驱动
。很多时候只关心页面长什么样子,发了什么请求拿了什么数据。于是在业务概念上每个人理解的深度都不同。解这个问题可能采用新的领域驱动设计的开发方式会比较合适。
什么是领域驱动设计?
DDD中的模型
Model与传统的POJO(DTO、DO、DAO)类等对比,都是一个类中有属性、属性有Get/Set方法,并且做传输对象。 Model与传统MVC三层架构层的业务逻辑层中的Service对比,都是处理业务行为(Action)层。 模型(Model)承载着业务的属性和具体的行为,是业务表达的方式、是 DDD 的内核。是一个类中有属性、属性有Get/Set方法,并且业务的行为(Action)操作也是在模型类中(充血模型)即做业务逻辑处理,又做数据传输对象,模型分为Entity、Value Object、Service这三种类型。 前面说的都是服务端术语。 简单来说,将业务概念优先于代码库的其它分类类型(例如,按文件类型分组)。这意味着,你应该基于你主要的业务领域(“问题”)及其子领域(问题的细分部分)来组织你的代码。例如,在电子商务领域,我们有产品目录、客户、订单、库存等子领域。 虽然DDD概念来自面向对象编程,依赖于类及其关系,但其核心理念可以很容易地应用到其它范式。
前端应用领域模型(来自: 前端开发-领域驱动设计 · 语雀 )
领域模型很多情况下都是由后端同学建立的,前端同学如何指导开发呢?
-
理解后端领域模型
- 弄清他们的模块划分,我们可以直接借鉴他们的模型,这样也可以保证前后端对于业务模型的理解一致。
-
建立前端领域模型
-
分离领域层
强调的是领域层的建设一定不是两个页面同时发了个请求,于是把这个请求抽出来,给与一个领域的名字。他一定被 提前建立好
的。在开始进行前端设计之前就被设计出来的一层。
我们要将所有页面组件与模块内的业务行为都抽离出来,放在合适的领域模块中。只要是业务行为, 一定有一个领域模块可以落
。如果不行就是领域模型设计的不合理。
驱动领域层分离的目的并不是页面被复用,这一点在 思想上
一定要转化过来。领域层并不是因为被多个地方复用而被抽离。它被抽离的原因是:
-
领域层是
稳定
的(页面以及与页面绑定的模块都是不稳定的) -
领域层是
解耦
的(页面是会耦合的,页面的数据会来自多个接口,多个领域) -
领域层具有
极高复杂度
,值得单独管理(view层处理页面渲染以及页面逻辑控制,复杂度已经够高,领域层解耦可以轻view层。view层尽可能轻量
是我们架构师cnfi主推的思路) -
领域层
以层为单位
是可以被复用
的(你的代码可能会抛弃某个技术体系,从vue转成react,或者可能会推出一个移动版,在这些情况下,领域层这一层都是可以直接复用) -
为了领域模型的持续
衍进
(模型存在的目的是让人们聚焦,聚焦的好处是加强了前端团队对于业务的理解,思考业务的过程才能让业务前进) -
主导接口约定
接口约定尽量由 前端主导
,毕竟接口是给前端使用,前端来设计接口比较合理。
- 开发中注意业务含义
在类,方法,模块命名时要直指 业务核心
,保持与领域模型的一致。
- 实时同步
确保团队内部所有同学都要熟悉系统的模型。尤其是对于要熟悉并修改代码的新同学,先向他们分享我们系统的领域模型之后再介绍技术架构。工作开展的重点的不同会导致编程世界观的不同。这样子会让新同学养成习惯,在进行技术决断之前先判断是否符合现有的模型。不断的思考模型,才能够帮助我们业务成长。
在 react 中领域驱动设计?
按照业务划分好模块,组织结构,视图与逻辑分离,一般来说:src目录下应该只含有 assets,pages,layouts,app 四个。
-
按功能划分文件夹,每个功能只能包含以下四种文件:Xxx.less, Xxx.tsx, useXxx.ts,useXxx.spec.ts , 采用嵌套结构组织,同时,结合 hooks 来做到相关状态逻辑收敛与复用
-
一个文件夹包含该领域内所有逻辑(视图,样式,测试,状态,接口),禁止将逻辑放置于文件夹以外
-
如果需要由其他功能调用,利用控制反转(依赖注入)SOA 进行组合
以上,也符合最小依赖,高内聚的原则,在 React 实践DDD,关键就是用好 hooks !
DDD
可以说是整个软件开发架构设计的趋势,前端中微服务实现其实也是依赖以此,把大的项目拆成相对独立的微应用,这就是划分为一个个的域。
参考
-
www.yuque.com/mayiprotote…
-
www.infoq.cn/article/a7e…
-
Hexagonal Architecture by example - a hands-on introduction
-
jishuin.proginn.com/p/763bfbd5e…
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!