Skip to content

Latest commit

 

History

History
55 lines (28 loc) · 5.78 KB

浅谈ddd在前端的应用(前言).md

File metadata and controls

55 lines (28 loc) · 5.78 KB

前言

前端开发面临的困难

这里我们讲到的困难并不是指技术细节实现层面上的困难,而是从整个软件开发过程中,遇到对高复杂度业务的开发困难。比如说很难从代码中直观地看出业务逻辑,项目经历不同人手迭代导致的逻辑书写规范不一致而进一步导致的后续人员理解成本高昂,说简单点,就是在高复杂度的业务之上,开发人员没有很强的意识去简化逻辑,将业务知识直接体现在代码中,我们具体从以下几个点来讲解这个问题。

业务逻辑本身错综复杂

这一点作为开发者是很难避免的,在一个项目中,必然会存在一些逻辑复杂的业务,初始开发者是最能够理解该业务的每个细节的,将业务映射成实际的代码过程中,复杂的业务转换成的代码肯定是也是复杂的,如何将其直面地转换成更易理解的代码,让后续维护者阅读代码就能大致理解其业务逻辑概貌,而进一步提升维护者开发的信心。

对全局业务理解不够透彻

一个项目在开发过程中人员变动是很正常的,可能是前人离职后人接手,也可能是新增人手,新人对业务的理解往往是不够透彻的,可能一来就直接评审接着就进入开发,比如新增了一个接口需要将数据展示在页面上,该需求前因后果并不知晓,这就形成了一种“面向页面”开发模式,对业务不熟悉,自然无法合适地将新的需求代码融入整个项目体系中。

知识在团队传播中的丢失

复杂的业务逻辑知识在团队中很难传播,在人员的变动后,更是支离破碎,业务知识丢失后,开发者就会陷入“不知在哪改、不敢改、不愿改”的泥淖中,最终导致业务开发不下去,推倒重来,严重影响整个项目的进展,我们在这里能做的,就是尽量将代码写成既能运行又能展示业务逻辑知识的形态,让后续的维护者更有信心的面对“知识丢失”这一困境。

团队无法形成统一逻辑代码书写规范

这里指的书写规范并不是指 eslint 之类的 style 规范,而是书写业务逻辑的位置、方式、分层、复用等,比如 A 为了将应用隔离而习惯将接口写在 UI 层直接处理数据,B 习惯将接口写在 common 模块供自己或者别人在 UI 层调用,A 习惯将 util 类工具函数直接和 api 接口混在一起写,而 B 更愿意将 util 类函数写得更通用放在 common 模块,假如新来了开发者 C , C 看到各式各样的风格就会很疑惑,不知应该按照 A 还是 B 或者按照自己的习惯书写,随着开发人员越来越多,直接会导致了整个项目逻辑书写规范的崩溃,维护者的维护信心会大打折扣。

常见的问题

  • 业务逻辑过于集中在视图层,导致多平台无法共用本应该与平台无关的业务逻辑,例如一个产品需要维护 Mobile 和 PC 两端,或者同一个产品有 Web 和 React Native 两端;

  • 产品需要多人协作时,每个人的代码风格和对业务的理解不同,导致业务逻辑分布杂乱无章;

  • 对产品的理解停留在页面驱动层面,导致实现的技术模型与实际业务模型出入较大,当业务需求变动时,技术模型很容易被摧毁;

  • 过于依赖前端框架,导致如果重构进行框架切换时,需要重写所有业务逻辑并进行回归测试。

  • 组件里面随便一个方法直接就修改了业务逻辑,保持业务逻辑的完整,完全凭程序员对系统的了解。

从分层的角度(mvc,mvvm)来看

mvvm在前端的应用非常的广泛,但是mvvm不是全新的模式,而是源于mvc。一般而言mvvm是框架给予我们的便利,最大的好处是避免了手动维护dom的状态,减少了mvc中c层的负担。

可是随着业务复杂度的增加,即使无需手动维护dom状态,也需要大量的代码实现业务逻辑,这样一来c层的负担越来越重。最常见的烂做法就是,将获取数据,业务逻辑等一股脑的写在组件里,形成了一个“胀血组件”,而这些组件往往是按照页面的结构来划分,这导致即使是一个业务动作,它的业务逻辑还是散落在各个组件中,当我们需要修改的时候不得不查看所有的组件的相关逻辑和数据流动,还需要担心由此带来的其他影响,当一个具有几万行代码的复杂模块使用页面驱动来编写业务逻辑的时候,其维护性可想而知。

当页面有复杂的交互的时候,vm处理页面的状态已经自顾不暇了,不应该再将复杂的业务杂糅在组件里面。

在前端如何合理的运用DDD解决这些问题

DDD(Domain-Driven Design 领域驱动设计)是由Eric Evans最先提出,目的是对软件所涉及到的领域进行建模,以应对系统规模过大时引起的软件复杂性的问题。

在前端开发中遇到的问题可以归纳到两种复杂度:技术复杂度(视图层的人机交互),业务复杂度(实际业务的复杂多变),

那么我们就可以得到一个大概的方向--隔离业务复杂度和技术复杂度

怎么隔离

--鲁迅曾经说过:没有什么是增加一层抽象解决不了的,如果不行就再加一层。

如果你读过《领域驱动设计:软件核心复杂性应对之道》这本书,你会发现DDD是一个很重的概念,里面包含了太多的概念,DDD中的领域划分,限界上下文与领域的关系,聚合?聚合根?什么是实体,什么是值对象?谁是领域专家?六边形架构?DDD的概念兴起于后端,在前端使用需要一定的变通,我建议在前端仅仅抽离出领域层(entity 和 service),将视图层和业务逻辑即可。