`

前后端分离——Web 研发模式演变

 
阅读更多

前不久徐飞写了一篇很好的文章:Web 应用的组件化开发。本文尝试从历史发展角度,说说各种研发模式的优劣。

一、简单明快的早期时代

1

可称之为 Web 1.0 时代,非常适合创业型小项目,不分前后端,经常 3-5 人搞定所有开发。页面由 JSP、PHP 等工程师在服务端生成,浏览器负责展现。基本上是服务端给什么浏览器就展现什么,展现的控制在 Web Server 层。

这种模式的好处是:简单明快,本地起一个 Tomcat 或 Apache 就能开发,调试什么的都还好,只要业务不太复杂。

然而业务总会变复杂,这是好事情,否则很可能就意味着创业失败了。业务的复杂会让 Service 越来越多,参与开发的人员也很可能从几个人快速扩招到几十人。在这种情况下,会遇到一些典型问题:

1、**Service 越来越多,调用关系变复杂,前端搭建本地环境不再是一件简单的事。**考虑团队协作,往往会考虑搭建集中式的开发服务器来解决。这种解决方案对编译型的后端开发来说也许还好,但对前端开发来说并不友好。天哪,我只是想调整下按钮样式,却要本地开发、代码上传、验证生效等好几个步骤。也许习惯了也还好,但开发服务器总是不那么稳定,出问题时往往需要依赖后端开发搞定。看似仅仅是前端开发难以本地化,但这对研发效率的影响其实蛮大。

2、**JSP 等代码的可维护性越来越差。**JSP 非常强大,可以内嵌 Java 代码。这种强大使得前后端的职责不清晰,JSP 变成了一个灰色地带。经常为了赶项目,为了各种紧急需求,会在 JSP 里揉杂大量业务代码。积攒到一定阶段时,往往会带来大量维护成本。

这个时期,为了提高可维护性,可以通过下面的方式实现前端的组件化:

2

理论上,如果大家都能按照最佳实践去书写代码,那么无论是 JSP 还是 PHP,可维护性都不会差。但可维护性更多是工程含义,有时候需要通过限制带来自由,需要某种约定,使得即便是新手也不会写出太糟糕的代码。

**如何让前后端分工更合理高效,如何提高代码的可维护性,在 Web 开发中很重要。**下面我们继续来看,技术架构的演变如何解决这两个问题。

二、后端为主的 MVC 时代

为了降低复杂度,以后端为出发点,有了 Web Server 层的架构升级,比如 Structs、Spring MVC 等,这是后端的 MVC 时代。

3

代码可维护性得到明显好转,MVC 是个非常好的协作模式,从架构层面让开发者懂得什么代码应该写在什么地方。为了让 View 层更简单干脆,还可以选择 Velocity、Freemaker 等模板,使得模板里写不了 Java 代码。看起来是功能变弱了,但正是这种限制使得前后端分工更清晰。然而依旧并不是那么清晰,这个阶段的典型问题是:

1、**前端开发重度依赖开发环境。**这种架构下,前后端协作有两种模式:一种是前端写 demo,写好后,让后端去套模板。淘宝早期包括现在依旧有大量业务线是这种模式。好处很明显,demo 可以本地开发,很高效。不足是还需要后端套模板,有可能套错,套完后还需要前端确定,来回沟通调整的成本比较大。另一种协作模式是前端负责浏览器端的所有开发和服务器端的 View 层模板开发,支付宝是这种模式。好处是 UI 相关的代码都是前端去写就好,后端不用太关注,不足就是前端开发重度绑定后端环境,环境成为影响前端开发效率的重要因素。

2、**前后端职责依旧纠缠不清。**Velocity 模板还是蛮强大的,变量、逻辑、宏等特性,依旧可以通过拿到的上下文变量来实现各种业务逻辑。这样,只要前端弱势一点,往往就会被后端要求在模板层写出不少业务代码。还有一个很大的灰色地带是 Controller,页面路由等功能本应该是前端最关注的,但却是由后端来实现。Controller 本身与 Model 往往也会纠缠不清,看了让人咬牙的代码经常会出现在 Controller 层。这些问题不能全归结于程序员的素养,否则 JSP 就够了。

经常会有人吐槽 Java,但 Java 在工程化开发方面真的做了大量思考和架构尝试。Java 蛮符合马云的一句话:让平凡人做非凡事。

三、Ajax 带来的 SPA 时代

历史滚滚往前,2004 年 Gmail 像风一样的女子来到人间,很快 2005 年 Ajax 正式提出,加上 CDN 开始大量用于静态资源存储,于是出现了 JavaScript 王者归来的 SPA (Single Page Application 单页面应用)时代。

4

这种模式下,前后端的分工非常清晰,前后端的关键协作点是 Ajax 接口。看起来是如此美妙,但回过头来看看的话,这与 JSP 时代区别不大。复杂度从服务端的 JSP 里移到了浏览器的 JavaScript,浏览器端变得很复杂。类似 Spring MVC,这个时代开始出现浏览器端的分层架构:

5

对于 SPA 应用,有几个很重要的挑战:

1、**前后端接口的约定。**如果后端的接口一塌糊涂,如果后端的业务模型不够稳定,那么前端开发会很痛苦。这一块在业界有 API Blueprint 等方案来约定和沉淀接口,在阿里,不少团队也有类似尝试,通过接口规则、接口平台等方式来做。有了和后端一起沉淀的接口规则,还可以用来模拟数据,使得前后端可以在约定接口后实现高效并行开发。相信这一块会越做越好。

2、**前端开发的复杂度控制。**SPA 应用大多以功能交互型为主,JavaScript 代码过十万行很正常。大量 JS 代码的组织,与 View 层的绑定等,都不是容易的事情。典型的解决方案是业界的 Backbone,但 Backbone 做的事还很有限,依旧存在大量空白区域需要挑战。

SPA 让前端看到了一丝绿色,但依旧是在荒漠中行走。

四、前端为主的 MV* 时代

为了降低前端开发复杂度,除了 Backbone,还有大量框架涌现,比如 EmberJS、KnockoutJS、AngularJS 等等。这些框架总的原则是先按类型分层,比如 Templates、Controllers、Models,然后再在层内做切分,如下图:

6

好处很明显:

1、**前后端职责很清晰。**前端工作在浏览器端,后端工作在服务端。清晰的分工,可以让开发并行,测试数据的模拟不难,前端可以本地开发。后端则可以专注于业务逻辑的处理,输出 RESTful 等接口。

2、**前端开发的复杂度可控。**前端代码很重,但合理的分层,让前端代码能各司其职。这一块蛮有意思的,简单如模板特性的选择,就有很多很多讲究。并非越强大越好,限制什么,留下哪些自由,代码应该如何组织,所有这一切设计,得花一本的厚度去说明。

3、部署相对独立,产品体验可以快速改进。

但依旧有不足之处:

1、代码不能复用。比如后端依旧需要对数据做各种校验,校验逻辑无法复用浏览器端的代码。如果可以复用,那么后端的数据校验可以相对简单化。
2、全异步,对 SEO 不利。往往还需要服务端做同步渲染的降级方案。
3、性能并非最佳,特别是移动互联网环境下。
4、SPA 不能满足所有需求,依旧存在大量多页面应用。URL Design 需要后端配合,前端无法完全掌控。

五、Node 带来的全栈时代

前端为主的 MV* 模式解决了很多很多问题,但如上所述,依旧存在不少不足之处。随着 Node.js 的兴起,JavaScript 开始有能力运行在服务端。这意味着可以有一种新的研发模式:

7

在这种研发模式下,前后端的职责很清晰。对前端来说,两个 UI 层各司其职:

1、Front-end UI layer 处理浏览器层的展现逻辑。通过 CSS 渲染样式,通过 JavaScript 添加交互功能,HTML 的生成也可以放在这层,具体看应用场景。

2、Back-end UI layer 处理路由、模板、数据获取、cookie 等。通过路由,前端终于可以自主把控 URL Design,这样无论是单页面应用还是多页面应用,前端都可以自由调控。后端也终于可以摆脱对展现的强关注,转而可以专心于业务逻辑层的开发。

通过 Node,Web Server 层也是 JavaScript 代码,这意味着部分代码可前后复用,需要 SEO 的场景可以在服务端同步渲染,由于异步请求太多导致的性能问题也可以通过服务端来缓解。前一种模式的不足,通过这种模式几乎都能完美解决掉。

与 JSP 模式相比,全栈模式看起来是一种回归,也的确是一种向原始开发模式的回归,不过是一种螺旋上升式的回归。

基于 Node 的全栈模式,依旧面临很多挑战:

1、需要前端对服务端编程有更进一步的认识。比如 network/tcp、PE 等知识的掌握。
2、Node 层与 Java 层的高效通信。Node 模式下,都在服务器端,RESTful HTTP 通信未必高效,通过 SOAP 等方式通信更高效。一切需要在验证中前行。
3、对部署、运维层面的熟练了解,需要更多知识点和实操经验。
4、大量历史遗留问题如何过渡。这可能是最大最大的阻力。

六、小结

回顾历史总是让人感慨,展望未来则让人兴奋。上面讲到的研发模式,除了最后一种还在探索期,其他各种在各大公司都已有大量实践。几点小结:

1、模式没有好坏高下之分,只有合不合适。
2、Ajax 给前端开发带来了一次质的飞跃,Node 很可能是第二次。
3、SoC(关注度分离) 是一条伟大的原则。上面种种模式,都是让前后端的职责更清晰,分工更合理高效。
4、还有个原则,让合适的人做合适的事。比如 Web Server 层的 UI Layer 开发,前端是更合适的人选。

历史有时候会打转,咋一看以为是回去了,实际上是螺旋转了一圈,站在了一个新的起点。

(完)

题图:演化真不容易呀。

分享到:
评论

相关推荐

    计算机软件体系结构 ——大型网站架构演变和知识体系

    软件体系结构为软件系统提供了一个结构、行为和属性的高级抽象,由构成系统的元素的描述、这些元素的相互作用、指导元素集成的模式以及这些模式的约束组成。软件体系结构不仅指定了系统的组织结构和拓扑结构,并且...

    Web编程入门——字节跳动.pptx

    Web 1.0 时期,网站主要是静态页面,用户只能浏览不能交互,而 Web 2.0 时期,网站变得更加 dynamic,支持读写、富交互、前端数据处理、前后端开发分离等功能。AJAX(Asynchronous JavaScript and XML)技术的出现也...

    dubbo——演变架构1

    分布式服务架构进一步将Web层和逻辑层分离,Web和Service部署在不同的服务器上,引入了远程过程调用(RPC)。RPC允许跨服务器的调用,是分布式系统中的核心。Dubbo作为知名的RPC框架,提供了高效的服务发现、治理和...

    大型网站架构演变和知识体系 讲解

    为了解决这一问题,网站架构开始进入第一次演变——**物理分离Web服务器与数据库**。 这一阶段的目标非常明确:通过将Web服务器和数据库部署在不同的物理服务器上来减轻它们之间的互相影响。这种分离有助于提升系统...

    电商项目-基于SSM+VUE的B2C电商项目

    这一结合不仅充分发挥了Java后端的强大处理能力,还利用了Vue.js的高效响应式特性,实现了前后端分离的设计模式,极大地提高了开发效率和用户体验。 1. **SSM框架详解** SSM是Java Web开发中常见的三大组件——...

    Java远程通信技术——Axis实战.doc

    随着技术发展,JAX-RPC演变为JAX-WS,引入了Java 5的Annotation特性,支持异步回调和面向消息模式,增强了Web服务的功能和灵活性。 **二、Axis 1.x实例** Axis 1.x版本是最早的Axis实现,主要用于创建、发布和消费...

    MVC_notes

    同时,随着技术的发展,如单页应用(SPA)和前后端分离等趋势,MVC模式也逐渐演变为VM(ViewModel)或MVVM(Model-View-ViewModel)等变种,但其核心思想——解耦和模块化,仍然被广泛采用。 总之,MVC模式是Web...

    ASP.NET源码——[CMS程序]微软内容管理系统Oxite.zip

    总之,"ASP.NET源码——[CMS程序]微软内容管理系统Oxite.zip"提供了丰富的ASP.NET MVC实战示例,对于提升开发者在.NET领域的技能,尤其是对MVC模式的理解,具有很高的学习价值。无论是初学者还是经验丰富的开发者,...

    精通Struts-基于MVC的Java Web设计与开发

    《精通Struts——基于MVC的...以上内容涵盖了《精通Struts——基于MVC的Java Web设计与开发》一书的主要知识点,通过学习这些内容,读者可以掌握使用Struts开发Java Web应用的基础,并理解MVC模式在实际开发中的应用。

    看透 Spring MVC 源代码分析与实践 —— 网站基础知识.docx

    详解 Spring MVC 源代码分析与实践 —— 网站基础知识 本文将从网站架构、网络传输、数据库优化、缓存、页面静态化、分布式数据库、NoSQL 和 Hadoop、高并发解决方案、应用和静态资源分离、CDN 底层优化等方面对 ...

    Agile Web Development With Rails 3rdEdition Beta

    标题与描述明确指出了本书的主题——敏捷Web开发与Rails框架的结合。这是一部专为Rails 2版本设计的书籍,作者团队包括了Sam Ruby、Dave Thomas、David Heinemeier Hansson等人,他们都是在Web开发领域有着深厚造诣...

    阿里云构建千万级别架构演变之路.doc

    这时,架构演进到了第二个阶段——物理分离Web应用和数据库。通过使用ECS作为Web服务器,同时配合RDS(Relational Database Service,阿里云的关系型数据库服务)作为独立的数据库服务,解决了资源竞争的问题,提升...

    C#设计模式大全

    桥梁模式是一个结构型设计模式,它将抽象与其实现分离,使它们可以独立变化。 - **结构**:包含抽象类、细化抽象类、实现者接口以及具体实现者类。 - **示意性源代码**:例如,创建不同品牌的电视。 - **实际应用**...

    Struts开发指南之MVC架构.doc

    #### MVC在Web开发中的演变 在Web项目的开发中,MVC模式的引入并非一帆风顺。早期,程序语言和HTML的分离难以实现,CGI程序通过字符串输出动态生成HTML,或者将脚本语言嵌入HTML中,这都使得程序语言和HTML难以分离...

    领域驱动设计与模式实战

    6.4.4 不要忘记不断演变的模式 6.4.5 分离单元测试和数据库调用测试 6.5 查询 6.5.1 单组查询对象 6.5.2 单组查询对象的代价 6.5.3 将查询定位到哪里 6.5.4 再次将聚合作为工具 6.5.5 将规格用于查询 6.5.6 其他查询...

    The_Django_Book_2.0_中文版.pdf

    通过MVC(后来演变为MTV)设计模式,将Web开发中的数据模型、业务逻辑和界面展示分离,从而大大提升了开发效率和代码的可维护性。Django的内置管理后台、ORM(Object Relational Mapping)数据库抽象层、以及模板...

    基于MVVM构架的Web前端框架研究

    该模式源自经典的MVC(Model-View-Controller),但更注重解耦视图(View)和业务逻辑(Model),并引入了一个中间层——ViewModel,来协调两者之间的通信。 1. **HCJ时代与AJAX时代的演变** 在早期的Web开发中,...

    看透 Spring MVC 源代码分析与实践 —— 网站基础知识.pdf

    标题 "看透 Spring MVC 源代码分析与实践" 提示我们主要关注的是Spring MVC这一Web开发框架的源代码分析和实际应用。Spring MVC是Spring框架的一个模块,它提供了处理HTTP请求、响应以及数据绑定等功能,是构建Web...

    JAVAWML信息查询与后端信息发布系统实现——WML信息查询设计(源代码+论文).rar

    Java WML(Wireless Markup Language)信息查询与后端...通过深入研究源代码和论文,可以学习到早期移动互联网应用开发的技术和实践经验,这对于理解现代移动开发的历史演变以及移动技术的发展趋势有着重要的参考价值。

Global site tag (gtag.js) - Google Analytics