做者 Kid 蚂蚁金服·数据体验技术团队前端
随着咱们解决的场景愈来愈专业化和复杂化,大型SPA应用的流行,前端承担的职责愈来愈多。代码的质量和系统的完整性愈来愈难把握。很容易致使迭代着迭代着发现代码改不动了。最后只能新起炉灶,从新开发。归根到底在于复杂度的失控
,本文会尝试分析其中的问题以及从前端如何应用领域模型
开发的角度给出一些建议。vue
咱们的系统架构精心设计过,按照标准的系统分层来管理复杂度。逻辑层
,展现层
,数据层
。每一层都精心设计。咱们抽象出独立的类来放通用逻辑。对着代码不断地重构,将有复用能力的点进行抽象。为何需求的变更仍是能常常摧毁咱们的设计呢。react
缘由在于:git
软件自己是为了管理复杂度,咱们如今面对的问题域错综复杂。为了建立真正好用的软件,开发者必须有一整套与之相关的知识体系。为此要知道的知识的广度让人生畏。一旦咱们不能理解问题域,咱们就无法作到控制问题域的复杂性。程序员
当复杂性失去控制的时候,开发人员就没法理解软件。当领域的复杂度没有获得解决时,基础技术再好的构思也无济于事。github
上面我所描述的设计都是技术层面
的设计。咱们很容易抽象出一个独立的类来放通用逻辑,但是很难给它业务上的定义
!这个通用类只有技术维度上的通用。数据库
问题在于技术维度上的通用很容易被业务摧毁
。需求上的变更或者膨胀,技术维度的通用很容易被摧毁。举个例子,页面变化了,某个视图组件被复用了,他可能就要被提取到上层的common目录。也就是技术模型马上须要从新设计,而后就是重构,重构成工程师喜欢的简洁的样子。而后需求再变化,再重构....陷入了怪圈。编程
而且这个阶段咱们很难保证重构的高效进行,有个理论叫破窗户
理论。一幢年老的大楼,一旦第一扇窗户破了,就会马上给人一种年久失修,腐败的迹象。就像是一辆车,一旦第一个车窗坏了,里面很快就会遭到破坏。后端
里面的根本缘由就是咱们设计的技术模型
与领域模型
不匹配。因而每次需求的改动,映射到技术模型的改动可能就是极大的工做量。甚至根本改不动,在业务压力很大的时候,咱们只能告诉产品经理,这个能够作,可是咱们须要2个月。结局极可能就是需求方的妥协,牺牲用户的利益。致使产品愈来愈难用。架构
任何项目都会丢失知识,外包出去的系统可能只交回了代码,知识没有传递回来。离职了,转岗了,一旦出于某种缘由人们没有口头传递知识,知识就丢失了。
丢失的知识也会致使系统愈来愈难维护,新同窗不知道对于通用逻辑的改动会发生什么事情,代码最终变成了“石油坑”,越陷越深,最终没法自拔。
以上这三个问题归根到底,就是咱们没有在前端代码里把咱们业务描述清楚。咱们不少状况下是视图驱动
,而不是业务驱动
。不少时候只关心页面长什么样子,发了什么请求拿了什么数据。因而在业务概念上每一个人理解的深度都不一样。解这个问题可能采用新的领域驱动设计的开发方式会比较合适。
领域模型是跨前端-后端-产品-设计的统一的语言。统一的语言既能够造成统一的理解,也能够促进领域模型的不断精化。也能迫使开发人员学习重要的业务原理,而不是机械的功能开发。产品经理也会不断提炼知识,升华自身理解。若是没有一个统一的,有共识的结构化的模型,必定会让项目很快的僵化,最后变成维护代价极高的遗留系统。
领域模型不少状况下都是由后端同窗创建的,前端同窗如何指导开发呢?我对于咱们系统的演进过程进行了总结,但愿能给你们一些灵感:
咱们在进行前端设计以前要搞懂咱们要开发的业务含义。除了本身理解创建模型以外咱们能够寻求后端同窗的帮助。拿到他们的领域模型
,弄清他们的模块划分。他们实际上是业务逻辑的最终实现方,咱们能够直接借鉴他们的模型,这样也能够保证先后端对于业务模型的理解一致。
咱们要绘制出前端的领域模型图,这个图与后端的领域模型图一致程度很高,但毫不是同样
的。一般比后端模型简单。好比页面须要进行一项任务的配置,这个配置在后端模型里可能会被解释的至关复杂(会被拿去作一些同环比之类的复杂操做),可是在咱们前端模型里,他的业务功能就是简单的任务配置而已~
如图,这一点是必须落到代码上的核心
!!必定要根据对应的前端领域模型在代码中分离出单独的领域层。模型必须与实现紧密结合,必定要指导设计,并落到代码上成为最终产品的一部分
。
还须要强调的是领域层的建设必定不是两个页面同时发了个请求,因而把这个请求抽出来,给与一个领域的名字。他必定被提早创建好
的。在开始进行前端设计以前就被设计出来的一层。
咱们要将全部页面组件与模块内的业务行为都抽离出来,放在合适的领域模块中。只要是业务行为,必定有一个领域模块能够落
。若是不行就是领域模型设计的不合理。
要明白,驱动领域层分离的目的并非页面被复用,这一点在思想上
必定要转化过来。领域层并非由于被多个地方复用而被抽离。它被抽离的缘由是:
稳定
的(页面以及与页面绑定的模块都是不稳定的)解耦
的(页面是会耦合的,页面的数据会来自多个接口,多个领域)极高复杂度
,值得单独管理(view层处理页面渲染以及页面逻辑控制,复杂度已经够高,领域层解耦能够轻view层。view层尽量轻量
是咱们架构师cnfi主推的思路)以层为单位
是能够被复用
的(你的代码可能会抛弃某个技术体系,从vue转成react,或者可能会推出一个移动版,在这些状况下,领域层这一层都是能够直接复用)衍进
(模型存在的目的是让人们聚焦,聚焦的好处是增强了前端团队对于业务的理解,思考业务的过程才能让业务前进)这里想引用下咱们leader导演的话说,咱们的竞争力毫不仅仅只是前端,咱们的竞争力在于咱们是数据部门的前端,在于咱们对于数据业务的理解。只有对于业务有深层次的理解,才能将系统带到正确的轨道上来。
接口约定尽可能由前端主导
,毕竟接口是给前端使用,前端来设计接口比较合理。并且在约定的过程当中,前端同窗又多了一次熟悉后端是如何分模块的机会。必须经过看后端同窗的数据库和总体的设计文档来约定接口路径和变量名称,也可以让先后端同窗对于系统的各部分的命名一致。
咱们在类,方法,模块命名时要直指业务核心
,保持与领域模型的一致。好比一条员工数据记录可能会被翻译成 inputRec或者employeeData, inputRec其实就是一个计算机思惟的术语,而employeeData才是直指问题领域。这个错误其实很容易犯,咱们开发的程序员思惟根深蒂固
。
确保团队内部全部同窗都要熟悉系统的模型。尤为是对于要熟悉并修改代码的新同窗,先向他们分享咱们系统的领域模型以后再介绍技术架构。工做开展的重点的不一样会致使编程世界观的不一样。这样子会让新同窗养成习惯,在进行技术决断以前先判断是否符合现有的模型。不断的思考模型,才可以帮助咱们业务成长。
领域驱动设计对于下降项目的复杂度上是明显效果的,并且将前端的代码业务逻辑和视图逻辑解耦。能够作到业务逻辑层的复用。加深了前端同窗对于业务的理解和思考,能够促进业务发展。这种分层思想并不局限在某个框架下,建议你们尝试下~
对咱们团队感兴趣的能够关注专栏,关注github或者发送简历至'tao.qit####alibaba-inc.com'.replace('####', '@'),欢迎有志之士加入~