前后端分开开发,只有json来交流。后端提供数据接口,剩余工作由前端完成。
在业务逻辑复杂的系统里,我们最怕维护前后端混杂在一起的代码,因为没有约束,M-V-C每一层都可能出现别的层的代码,日积月累,完全没有维护性可言。
虽然前后端分离没办法完全解决这种问题,但是可以大大缓解。因为从物理层次上保证了你不可能这么做。
One Page, One Application(后面缩写为OPOA,或者1P1A),含义很简单:一个页面就是一个应用。在众多的基于Web的MIS系统中,没有人关心页面的组织形式;大多数稍微复杂的MIS系统,都采用分祯 (Frame)的方式来组织页面,这样,在进行业务操作的时候,url的变化表现在一个框架页面内,从浏览器的地址看起来,只有一个地址;更有甚者,一些应用干脆弹出一个去掉了浏览器菜单、工具条、地址栏、状态栏的窗口(比如招商银行、民生银行的网上银行系统),连地址都看不见。因此,一个页面就是一个应用,从用户的角度来说,对于操作型系统,是一种非常自然的体现。用户无需了解每一个具体的操作对应的地址是什么。
这种设计背后的含义实际是:是希望由程序来控制用户的行为,还是反过来。在操作型系统中,每一步的操作往往被业务含义严格定义,无论是应用的设计者,还是其使用者,都希望在一种受控的状况下来进行操作。
OPOA的设计只能针对那些对URL不敏感的系统,或者说操作型系统。绝大多数MIS系统都属于这一范畴,Email系统也是这一范畴,其他领域,如监控系统,聊天室等都可以采用这种思路。反面的例子是,对于内容型系统,如新闻系统,Blog系统,论坛系统,用户更希望能够通过一个明确的 URL来定位页面内容,搜索引擎也喜欢这种地址。这种应用需要的是一个合理,易懂,明确的地址。
要说的一种实现是,采用AMOWA/AJAX技术来实现真正意义上的OPOA. 简而言之:主页面(或者称布局页面)只加载一次,其他的操作页面通过AMOWA/AJAX技术来加载,并将其中的操作脚本与布局内容分开,最后进行展示。
OPOA的架构示意图如上,如果我们单看一个逻辑页面(一个时间点浏览器中的全部内容),分析一下有几个特点:
1 页面完全由前端构建拼装,Backbone等框架的任务是把页面中的视图排排好
2 多数情况由视图来发起其所需的数据请求,所以会有多个Ajax请求或并行、或串行的发生
3 服务端的数据接口提供独立的http服务。
为什么说OPOA是最彻底的前后分离方案?首先,这里的分离是浏览器端和服务端的真正分离,跟“前”与“后”这个说法更贴近:);当然更主要是前后端的在物理位置上的鸿沟,客观要求服务端纯数据接口化的改造必须进行的彻彻底底;此外,“彻底”还表现在:OPOA额外的好处是对前端性能有帮助,复杂交互组件所需的JS和模板,无需重复加载、运行,给系统易用性带来帮助。
OPOA更适合一个页面不太多,但交互复杂的系统。如果系统中的众多页面长的根本不一样,多页面间也没有太多重复的组件,那么OPOA带来的性能提升就很小了。而且OPOA架构本身也有着难以解决的问题:
1 OPOA最大的问题是搜索引擎不友好,虽然已有多种为Spider提供内容的方案,但依然对SEO有伤害,这对很多网站而言是致命的。
2 OPOA中复杂页面,往往请求数较多,在PC端没有问题,但对于移动端而言就不那么美观了。
抛开SEO不谈,在多端时代,OPOA依然需要进一步进化,目标是来解决请求数较多的问题。
如上图所示,我们要做的是“动态数据的Combo”(这样说,是方便大家对比常见的静态JS、CSS的Combo),即:
1 前端:我们需要一个动态请求管理器,将多个请求集中起来,发送给后台服务。
2 后端:我们需要一个请求分解到多个子服务,再将多个子服务返回的数据Combo后返回。
所以这就是一个这种的方案,模板与json共存的方式,但是这种方式存在一个问题,就是模板归谁来管理。比较好的方案是前端。
在这个过程中,阿里作了一些尝试,那就是引入Node层,在这一层把模板与数据进行合成,然后浏览器拿到的就是生成好的HTML了,但也不是所有HTML都是这么生成好的,还是会有一些内容等到了浏览器之后,再用js去加载和生成。
在上上小节我们分析过,如果一个系统多个页面之间并没有太多重合,页面间没有太多需共用的复杂的交互组件,那么OPOA就不是必须的。这时候我们还能不能做到前后分离呢?我们回到前后分离的初衷:
1 单一数据源多展现端支撑
2 前后端基于接口定义独立并行开发
3 前后端独立发布
我们基于上一张图,而不是OPOA之前的传统网页架构去理解所谓“Node负责展现层”相关技术方案,会更容易循序渐进的发现它的实质。
无论哪种标榜“前后分离”架构服务端纯数据接口化的改造都是必须的,我们做到这一点之后,在使用Node负责展现层的架构中,就还有两个任务需要完成:
1 Action1:将动态请求Combo的相关逻辑,用Node实现,包括页面多数据区块对于数据需求的统一管理,以及统一获取。
2 Action2:将Backbone等前端OPOA框架中对于路由、视图的管理移植到Node中。
做完这两项任务之后,在浏览器端的表象上,网页从单页应用的Web Application回归到传统的多页Web Page模式。但是通过良好的设计,我们依然可以拿到做“前后分离”最想要的那些好处。
在多端时代,服务端纯数据接口化改造是大势所趋,这客观上给“前后分离”提供了更大的舞台。一个传统多页型网页系统在完成服务端接口化改造之后,需要做的事情有两个:统一管理构成一个页面的所有数据需求,完成页面拼装并输出。
而单就这两个任务而言,Node应该说不是必须的。Node的异步特性,高并发能力都不足以成为其在服务端多语言竞争的环境里获胜的核心优势。
我认为引入Node的优势有两个:
1 促进前后端更好的分离,就像CSS出现之后,我们不再用标签定义文字样式一般,引入不同的技术、不同的语言可以让每个模块所承担的职责更加界线清晰,进而让服务端纯接口化改造更彻底、更坚定。“前”与“后”在服务端进行分离,OPOA中浏览器与服务端在物理位置上的鸿沟不再存在,那么新的语言和技术是划分边界这一任务的继承者。
2 促成前端工程师和后端工程师在开发时的解耦,面对明晰的接口定义,前端工程师可以和后端工程师并行无交集的开发,直到最后阶段联调。这可以带来研发效率上的极大提升。
“天下武功、唯快不破”,无论是做彻彻底底的OPOA,还是用Node做展现层服务,它们所带来的研发效率方面的提升才是架构革新的源动力。