问题
- “一云多端”成为趋势,终端类型越来越多。比如,现在PC Web网站的产品已经有了,现在想扩展App,小程序... ...怎么办?一个直接能想到的方法就是在原来的基础上,为APP等增加API接口,如下图所示:
这样做是可以的,然而一旦遇到修改,那么要同时修改几个端的代码,很麻烦,不是很完美。
- “前后端分离”成为趋势。一开始的PC Web网站,大多是采用服务端渲染的前后端一体化的模式。随着技术的发展,前后端分离,前端渲染逐渐成为趋势。相应地,前端开发人员也从后端团队中独立出来。
现在兴起的APP,小程序等,天生就是前后端分离的。前端,APP,小程序等各自独立成专门的团队,当然可以满足这种趋势。相应地服务端需要为每一个前端部门提供服务,在实践中常常发现,重复的内容很多,有没有办法增加复用?或者说后端能否只对接一个“大前端”部门,剩下的“大前端”部门内部自己解决?
- 服务端设计的API接口,面向通用服务,还是面向UI?各个端对数据的显示要求不同,给一个公共的API还是分别给不同的API?
比如,时间显示,PC端可能要求“2020-8-9”的格式,而APP端可能要求“2020/8/9”的格式,接口怎么给?
再比如,相同功能的一个接口,PC Web端需要20个字段,已经做好了。现在APP端因为屏幕小,只要10个字段就够了,是复用老的API,让APP忍受垃圾信息,还是为APP额外新增一个接口?
前端和服务端人员可能会有不同意见,这就带来了冲突。大家都有一定的道理,怎么协调?
- 产品经理提出PRD-》UED设计交互稿-》UI设计界面-》后台设计API接口-》后台实现服务-》前后端联调... ..
从现状来看,前后端分离之后,服务端直接给各种端提供服务是很自然能够想到的一种方式。这种方式的优点是简单直接,缺点是不够灵活。因此,考虑在前端和后端之间插入一个中间层,作为前后端之间的桥梁,增加灵活性。
对于这个中间层的称呼,一种是“网关层或者接入层”,这个可能会和后台现有的网关和接入层造成混淆。另一种叫法叫做BFF(Backend for Frontends,为前端而存在的后端),这种称呼相对比较准确,不会带来混淆。
- BFF(Backend for Frontends,为前端而存在的后端)
解决方法
- 针对“一云多端”,可以在BFF层做适配。可以考虑MVVM的模式,从服务器来的数据当做Model,在BFF中针对各种端,提供不同的ViewModel。如果数据变了,只要修改Model就可以了。如果要增加一种端,只要增加一个ViewModel就可以了。在这里集中修改,就可以解放各个终端的格式转化工作。
- “前后端分离”之后,各种端可以融合为一个“大前端”,跟后端对话的窗口就是BFF。对于后端来说,只要满足BFF的数据需求就可以了,剩下的事情,就让“大前端”内部自己解决。
- 服务端设计的API接口,面向通用服务,不需要面向UI。各种端的UI差异,由BFF层负责适配。这样的话,可以让后端更加专注于业务逻辑和数据服务,不需要操心各种端的差异。
- 整个开发流程太长,导致相互等待,造成浪费。针对这个问题,可以考虑在BFF层将开发流程分为两部分。“大前端”作为一个独立开发部门,领先后端一个版本发布周期。
具体做法是,对于新业务,将Mock数据生成在BFF层,对于各种端来说,相当于后端服务已经好了,可以直接进行联调,不需要等待。这样就把前端对后端的数据依赖去除了,更加灵活。
组织结构
针对上面提到的“大前端”技术架构,需要相应的“大前端”组织结构相对应。
分类思路
- “大前端”是针对整个后端来说的,所以这一层是按照职能来分的
- 在“大前端”下面,是否仍然按照职能来分呢?比如IOS开发,Android开发,H5开发等等。这种分法是可行的,然而收益不是很大。这只是将一个个小部门“组合成”一个相对大的部门,融合度不是很高。另外一种融合度更高的划分方法是在“大前端”下划分为“基础服务”,“业务开发”两个子部门。
- “基础服务”的主要职责是为整个“大前端”部门提供公共服务,公共组件,周边设施等等。根据需要和实际情况可以分为“架构”、“工具”、“组件”等小组
- “业务开发”的主要职责完成业务部门的需求。根据业务发展情况,按照具体业务划分小组
管理
管理方式跟组织结构相适应,采用职能管理和敏捷管理相结合的方式。
职能管理
“大前端”是按照职能分的,跟后端相对应,是技术部下面的一个子部门,按照职能管理方式进行统一管理。
敏捷管理:
- “大前端”内部,主要还是按照业务分组的,并且由于BFF的引入,“大前端”内部可以形成开发的闭环,可以考虑引入敏捷管理。
- 要实行敏捷管理,需要产品和测试的支持。根据业务,将相关的产品、设计、测试、开发(“大前端”)组成虚拟团队。
流程
和管理模式相对应,采用瀑布模型和敏捷模型相结合的方式。
瀑布模型
职能型组织,采用瀑布模型的开发流程是合适的。产品部,技术部,测试部一般跟产品开发相关度比较大,按照瀑布模型联系起来。这里考虑前后端分离的开发模式,“大前端”可以独立完成开发闭环,虽然BFF层的数据是Mock的。
另外,大前端版本的开发要求领先后端一个版本以上,这样也方便对于后端服务的测试。简单讲,就是将通常的“后端功能推动型”改为“大前端产品拉动型”
- 产品PRD -》交互/UI设计 -》大前端开发 -》大前端测试 -》大前端内部发布
- 后端服务开发 -》后端测试 -》对接大前端合适版本(主要是BFF的工作,Mock数据改为从后端服务取数据) -》预发环境验证 -》产品上线
敏捷模型
产品,测试,大前端可以考虑合作,按照敏捷模型进行开发。目的是打破部门墙,加强沟通;以业务开发为共同目标,形成合力。
- 开发周期为4周,按照1周预研、2周开发测试、1周重构的比例进行分配。
- 1周预研:这周的主要任务是产品、测试、开发进行充分沟通,对这一期的业务目标达成共识。
产品的主要工作是讲解需求、原型、设计,进行场景化的描述,定出优先级,确保团队成员对本期业务有正确的理解。
测试的主要工作是进行测试用例编写,用例评审,最终通过相应工具,将测试用例数据在BFF层形成可执行的Mock数据。
开发的主要工作是根据业务需求进行技术预研,技术选型,技术设计,任务划分,工作评估等等。完成“计划会议”所要求的内容,将开发任务分配到人。
- 2周开发:按照敏捷的模式进行开发,将业务落地。“每日站会”要坚持开,及时沟通。开发每完成一项,测试就可以直接验证,注重效率。Mock数据由测试统一负责,开发测试用同一套数据,减少误会。这期的结束标志是2周之后的“评审会议”,开发测试向产品演示完成的业务场景。
- 1周重构:这周对应的是敏捷开发里面的“回顾会议”,也是产品、测试、开发进行充分沟通的一周。产品在公司内部试运行一周,进行验收,收集反馈,为下一期的产品设计提供数据支持。开发一方面可以修改bug,更重要的是根据“回顾会议”的内容,进行流程改进,对“技术债”及时进行重构。也可以进行组件开发,提高今后代码的复用度。
特殊之处
Mock数据
- 以前的Mock数据由开发自己负责,要么直接代码写死,要么借助Charles等工具。现在,将Mock数据由测试统一负责,直接生成在BFF层。
- 以前开发要写自测代码,单元测试代码;测试设计出用例数据之后,一般通过流程工具,比如JIRA,要求开发自测。现在的模式是测试专职维护BFF上的Mock数据,将设计的用例转化为实际可用的Mock数据,开发测试用同一套标准,减少流程和沟通上的损耗。
内部版本
- “大前端”开发测试完成的内部版本是半成品,是缺乏后台实际支撑的。内部发版之后,在内部的测试服务器上试运行。(开发版本运行在开发服务器上)。运行需要的数据由测试负责Mock。
- 这个内部版本不能交给实际的用户使用,但是内部的产品,开发,测试可以使用,用来体验,查找bug等等。
- 对于后端开发来说,也很便利,服务开发好之后,有现成的产品用来测试,能省很多事。
- 向老板汇报,或者向客户展示,也很方便,有实际可用的产品可以体验,虽然数据是Mock的。这个跟看word文档,ppt,原型设计,或者UI图,感觉是完全两样的。
- 修改成本小,一般来说,70%的工作在后台开发,30%的工作在“大前端”页面。在内部试用的那一周中,发现的问题,或者需求变更,可以非常容易的在下一个版本迭代完成。这个时候,后台服务的开发还没开始,或者刚刚开始,变更成本很小。
需求拉动
- 以前,想开发一个功能,首先考虑的是后端逻辑是怎么样的。很多时候,要根据后端现有的逻辑,修改页面的展示,交互的顺序等等。是一种“后端功能推动的模式”
- 现在,产品和“大前端”一起,领先后端至少一个迭代以上。遇到需求变更强烈的点,或者争论较大的点,可以考虑让内部版本运行时间长一点,比如领先两三个版本。等产品想清楚了,基本稳定了,后端再上。这样,产品思考问题的重点,就从后端现有的功能转移到客户现实需求上来。“需求拉动型开发模式”,解放了产品的思维,更容易设计出符合客户期望的产品。
- 原来的模式是由后端推着前端走,现在的模式是产品和前端拉着后端走,思维模式是完全不一样的。
- “大前端需求拉动型开发模式”:先有个可用的产品,搞清楚用户喜欢什么,再接上后端实现。
- “后端功能推动型开发模式”:先做需求分析,评估现有后端功能,然后想办法满足客户需求。
- 问题是:“客户或者用户知道自己想要什么吗?需求分析能有效吗?”。相对来讲,如果有个可用的东西,真正用起来了,用户更加容易知道自己想要什么。比如“这个颜色最好改一下”,“这里的按钮碍眼,最好去掉”,“这里我想看更多的信息,最好能加上”。诸如此类
平稳的节奏
- 职能型组织,瀑布式开发模型,有利于控制风险,缺点是时间过长,一般项目至少1个月以上,面对需求变更能力较弱。是一种偏重计划的模式。
- 敏捷开发模式,有利于团队沟通,时间一般较短,一般是2~4周。至于风险,考虑较少,一般是先用了再说,发现问题,下个周期再改。是一种偏重经验的模式。
- 将这两者结合,是希望达到风险和速度的平衡,形成平稳的节奏。将敏捷模型中原本只有4小时的计划会议和回顾会议扩展为一周,是为了让跨部门沟通更充分,让产品验收更全面,降低风险。
- 集中资源做“重要而不紧急的事情”。客户需求很重要,但从想法到落地,并没有那么快。所以发挥“大前端”灵活的优势,让客户早一点看到想法落地,可以超越客户期望。
- “需求变更”本身,也是一种潜在的客户需求。在用上实际可用的产品前,很多时候,客户也不知道自己想要什么。所以,采用两阶段交付的方式,用总开发成本30%左右的“大前端”半成品,挖掘客户的潜在需求,可以提高客户的满意度。
- “可用的产品胜过完备的文档”,虽然是个半成品,站在客户的角度,比word文档,原型设计等更实在,更靠谱。
重视重构
- 技术债怎么办?是立即处理还是等累积到一定程度,再集中处理?
- 让业务停下,专门做重构,这种机会只能说可遇而不可求。
- 将原来敏捷中不超过4小时的回顾会议,扩展为1个星期的重构阶段,正是为了解决技术债不断累积的问题。达到“一边飞行,一边换引擎”的效果。
- 这个阶段,产品和业务也没有停,在试用,在体验,在验证一开始的设计理念是否符合实际。这样就促成了产品和技术的双赢局面。
重视预研
- 这里将敏捷开发中原本4小时的“计划会议”扩展为1周。
- 敏捷模型在介绍时有个假设,那就是需求确定,原型设计,UI资源,前后端接口设计等各种资源都准备好了,相关的可行性,也就是预研都完成了,再开“计划会议”
- 实际情况是,上面提的那些条件往往都没准备好,或者有缺失。开发在进行到一半的时候,经常发现交互逻辑不落地,要改原型。或者发现UI资源缺少,接口定义不合理等等。
- 特别是职能型组织,跨部门沟通,这种信息缺失的事情更容易发生。
- 在正式开发之前,花1周时间,集中进行沟通,进行技术预研,做好充分准备,将问题发现在工程开始之前,对减少不必要的返工是很有意义的。
面向BFF编程
- BFF成了“大前端”和后端之间的抽象接口
- BFF需要做好两边的适配
- 可以考虑将一些公共业务也接过来,实现“轻客户端”的目标
- 自然而然的“热更新”,BFF采用了后端的技术,做的是“大前端”的工作。有修改,更新服务,就生效了,天然的热更新。
- 天生的“跨平台”,BFF这一个地方修改,各种端都能起作用。
- 增加掌控力。BFF由企业维护,而各种端掌握在用户手里。将业务由各种端移到BFF,可以显著提供企业的掌控力。
这里的边界是:“能服务端(BFF)实现的,就不要放到客户端去,除非遇到严重的性能问题”。
- 注意性能瓶颈,这是关键节点,是前后端的对接点。并且还要注意,对接之后,Mock数据要清除干净,保证生产版本的数据是来自真正的后端。
效率和安全并重
- “大前端”注重效率,快速响应用户的需求变更。
- 后端注重安全,按照瀑布模型或者迭代模型,注重风险管控。
- 通过BFF解耦,让前后端各自独立运行。
思考
- “大前端”是最近起来的概念。和传统的前端相比,“大前端”有两个方面的扩展。一个是端的多样性,比如新增了iOS,Android,小程序,公众号等等。另外一个是往后端扩展,比如Node.js的兴起,或许写后端服务没有JAVA成熟,写BFF还是可以胜任的。
- “大前端”是相对于传统的前端,iOS,Android,H5等独立小团队而言的。从基础服务+业务支持两个方面,促进团队的融合。在架构,工具链,组件化等几个方面提高复用,提升效率。
- “大前端”是随着前后端分离的趋势逐步提出来的,是相对于后端来讲的,因此,要达到和后端既相互独立、减少依赖,又相互合作、沟通清晰的目标。
- “大前端”概念最初是从阿里传出来的,后来饿了么发展最出名,现在很多公司在用,和微服务一起,接受度也在增加,成为一种趋势... ...
- “大前端”在具体落地的时候,还没有固定的模式,各家的方案也不尽相同。有可供参考的成功案例,没有可供复制的成熟模式。需要根据自身的具体情况,摸索前进。