Web前后端:如何分离,如何解耦?
摘要:在本文中我们一起来探讨一下为什么要在软件开发中进行前后端的分离,如何做到前后端分离,如何解耦。
简单地说,就是要把复杂的问题简单化,把一个从0到N的问题转化为N个0到1的问题。另一个相近的说法就是“解耦”。
举个例子,我们接到一个客户需求,要求写一个应用,这个应用中有页面的切换,有对应页面的数据交互,数据的获取,数据的计算,如果把这些功能放在一个单一的应用中的话,从大局观的角度来看,这个单一的应用是比较复杂的。
为了降低这个复杂度,我们首先要做的就是前后端分开,关于前后端的定义,大体来说是这样的:前端负责的内容主要有页面路径管理,页面对应数据的显示与管理等等;后端负责的内容主要有数据的提供,数据的计算,安全性管理等等;前后端的通信一般通过HTTP请求来实现;当然这里也有个例外情况,比如有一部分功能可能要求实时性,像类似聊天类的功能,共享文档的功能,画板分享的功能,多人协同操作的功能等等,需要通过socketio这样的通信机制进行。
再细分一下讲,单一的程序框架模型会是MVC(Model-View-Controller)结构的。前后端分离以后,后端会有Model/Entity-Repository/Service-Controller,前端会有View-Model-API调用。
看一下前端部分,View主要是指网页的页面,手机端的页面(Android就是Activity,Layout和View等, iOS就是View Controller和UIView等),如果使用跨平台技术(如React Native, Flutter,Xamarin等)也离不开上述的概念,大同小异。这部分的处理当然离不开数据Model和API调用。处理好这些以后前端的任务也就做好了。
再看一下后端部分,界面相关的处理已经不再是后端的任务了,后端只需要通过API提供前端需要的数据就可以了。Controller就是用来定义这些API的,这一部分会分析或者计算出前端的输入和输出模型,具体处理方式有以下几个因素考虑:请求的类型如GET,POST, PUT, DELTE,PATCH等;数据From Body,数据From Route,数据From Form等等;数据处理完成以后,一个是通过API返回,一个是更新数据源,这里的数据源可以是数据库如SQL和NoSQL,可以是消息中间件如Kafka,也可以是数据缓冲服务器如Redis等等。通过上述的描述,我们可以看到后端的任务变得更加轻量级了,逻辑上也更加简单了。
所以,通过前后端的分离,我们把前端和后端的复杂度始终维持在可控的范围内。如果在软件开发中始终使用这种理念的话,我们会大大扩展我们的软件开发效率和程序质量。因为解决一个N难度的问题显然要比解决N个1难度问题要困难得多。对于一个N难度的问题,我们将其分解为N个1难度的问题之后,我们可以各个击破,步步为营,一步一个脚印,在工作中从容而且自信,因为我们始终用最简单的方法去解决问题。如果碰上复杂的问题,就再将其分化为多个难度为1的问题,以此类推。简单一些讲,就是要保证我们在解决问题的时候,不打无准备之仗,始终脚踏实地,分而治之,避免把我们自己架到火炉上烤。
复杂度降低以后,整个项目的维护成本和扩展成本都会非常的低。我们对项目开发的驾驭能力也会提高很多。
再说一个数据流向的问题,这个主要发生在前端。 这部分的处理会直接关联到前端程序设计的复杂度。在三大前端框架中有双向数据流向和单向数据流向,其中React只支持单向数据流向。但是目前有了Hooks机制以后,你可以通过传Setter和Getter两个Reference来达到修改数据的目的。这种通过传递参数到其他Component的模式实际上增加了程序的复杂度,因为一层层的传递使得组件之间的耦合性增强了。
那么如何解决这个问题呢?
在Angular中可以通过Service中定义Getter和Setter来解决这个问题,每个需要操作这个数据的组件都可以依赖注入这个Service,有了这个Service,就可以很轻松的读取和更新其中的数据了,对于数据的监听,可以通过在Service定义一个Subject,监听到数据变化以后,你可以更新界面,向服务器发送请求等等,这样做,组件之间的耦合性就大大降低了。
再说一下单向数据流向机制如Ngrx, VueX, Mux等等。单向数据流向机制在目前的前端开发中使用很普遍,然而,实际上这种机制会增加程序的复杂度。这个主要是因为这种机制会在前端开发层级中引入另外一套体系来维护数据的流向,假如我们对已有的业务定义为从0到1的实现,加上这个机制以后,就变成了0到1再加上另外一个0到1,变成了0到2的问题。这就变复杂了。
前端只要做好如下的任务如页面的切换,数据与后端的交互,数据模型与API的对应, 组件尽量的写成Self-Contained就可以了。
所以我不建议在前端中再额外的添加类似的数据流向机制了。
再谈一下后端的分析。我们在谈后端的时候,我们不太关心使用什么技术(Node JS,.net Core,SpringBoot,PHP, Python, Ruby On Rails等等),这是因为后端的逻辑是清晰的,不管你用那种技术,程序的设计的层级是大同小异的。
后端的主要任务是API数据的提供。比如用户相关的API,创建一个用户,更新一个用户,删除一个用户等等的操作都是在一个用户Controller定义相关的API。对于Controller的添加,我建议要根据业务层来添加,不要在一个Controller中做太多的事情。比如我们可以添加Book Controller来处理Book相关的操作,订单Controller来处理订单相关的操作。
这样做是为了把API设计变成线性的,平行的,各自Controller之间的耦合性降到最低,从而也就降低了复杂度。
进一步说,在实现的层级上,我们可以有Data Set对应数据库表格,Entity对应数据表格记录,Model对应API数据模型,Service/Repository负责逻辑实现等等。
在后端技术选取中,数据库相关的操作是一个不可逾越的门槛,有的框架使用类似EntityFramework的机制如.NetCore和PHP Laravel, 有的使用类似JPA Hibernate,Mybatis如Spring Boot,有的则直接使用JDBC SQL语句执行的方式,有的结合Stored Procedure。在这个地方,按照程序复杂度排序的话,由低到高分别是EntityFrameWork<JPA Hibernate+Mybatis< JDBC SQL < Stored Procedure。
当然,数据库的设计,数据库的升级Migration也都是关系到程序项目复杂度的因素。这个要结合具体的后端技术来谈。在本文中我们就不展开了。
好了,本文我们主要探讨了前后端分离的作用,如何进行前后端分离,如何解耦,有不足之处,请不吝指正。
Web前后端:如何分离,如何解耦?的更多相关文章
- Web前后端分离
第一篇博客:见谅 用自己的通俗语言讲web工程的前后端分离: 只是从自己的角度去分析,我眼中的前后端分离(可能不对) 首先要明白我们服务器和浏览器之前传输和接受的是什么: 静态文件(html,css, ...
- Web前后端分离开发(CRUD)及其演变概括
今天学习了前后端分离开发模式又从网上查了一些资料就写了一篇博客分享: 一.为什么分离前后端 1.1早期开发 1.2后段为主mvc模式 1.2.1Structs框架介绍 1.2.2Spring mcv开 ...
- web前后端分离漏洞分析防御
web前后端分离漏洞分析防御 漏洞分析,主要漏洞有 一.跨站脚本攻击XSS 程序 + 数据 = 结果:攻击后,数据夹杂一部分程序(执行代码),导致结果改变: 1.XSS攻击注入点 (a):HTML节点 ...
- 淘宝玉伯引发Web前后端研发模式讨论
淘宝玉伯是是前端基础类库 Arale 的创始人,Arale 基于 SeaJS 和 jQuery.不久前,淘宝玉伯在 Github 的 Arale 讨论页面上抛出了自己对于Web 前后端研发模式的思考. ...
- web前后端交互,nodejs
手机赚钱怎么赚,给大家推荐一个手机赚钱APP汇总平台:手指乐(http://www.szhile.com/),辛苦搬砖之余用闲余时间动动手指,就可以日赚数百元 web前后端交互 前后端交互可以采用混合 ...
- 如何简单区分Web前后端与MVC
MVC是开发所有软件所必须涉及的基本几个划分 M主要负责数据与模型,V主要负责显示C主要负责交互与业务所以不管是前端还是后端,都是有MVC的.MVC是一个对于软件简单的抽象,不管是M还是V,还是C都是 ...
- 前后端不分离部署教程(基于Vue,Nginx)
有小伙伴私信问我vue项目是如何进行前后端不分离打包发布的,那我岂能坐视不管,如此宠粉的我肯定是要给发一篇教程的,话不多说,开始操作 前端假如我们要发布我们的Vue项目,假设我们前端用的是histor ...
- web前后端安全问题
1. 安全问题主要可以理解为以下两方面: 私密性:资源不被非法窃取和利用,只有在授权情况下才可以使用: 可靠性:资料不会丢失.损坏及篡改: 2. web安全的层面 代码层面:写代码时保证代码是安全的, ...
- Vue 应用 nginx 配置 前后端不分离模式
一.先在官网下载nginx 软件,解压后放在软件盘中如D盘 将nginx 文件夹拖到编译器中,打开conf 文件夹中的 nginx.conf 文件,找到其中的server {} 配置项,默认35 行. ...
随机推荐
- 使用DataStax Java驱动程序的最佳实践
引言 如果您想开始建立自己的基于Cassandra的Java程序,欢迎! 也许您已经参加过我们精彩的DataStax Academy课程或开发者大会,又或者仔细阅读过Cassandra Java驱动的 ...
- Oracle (实例名/服务名)SID和Service_Name的区别
可以简单的这样理解:一个公司比喻成一台服务器,数据库是这个公司中的一个部门.1.SID:一个数据库可以有多个实例(如RAC),SID是用来标识这个数据库内部每个实例的名字,就好像一个部门里,每个人都有 ...
- 知识点干货——CSS动画
CSS动画 (transition.animation) //2D动画 transform:translate(); /*偏移*/ transform:rotate(); /*旋转角度*/ trans ...
- 阿里面试官:HashMap 熟悉吧?好的,那就来聊聊 Redis 字典吧!
最近,小黑哥的一个朋友出去面试,回来跟小黑哥抱怨,面试官不按套路出牌,直接打乱了他的节奏. 事情是这样的,前面面试问了几个 Java 的相关问题,我朋友回答还不错,接下来面试官就问了一句:看来 Jav ...
- 520是秀恩爱吃狗粮,521才是真正的告白日,- Python告白神器用起来 !
网络情人节是信息时代的爱情节日,定于每年的5月20日和5月21日,该节日源于歌手范晓萱的<数字恋爱>中“520”被喻成“我爱你” ,以及音乐人吴玉龙的网络歌曲中“我爱你”与“网络情人”的紧 ...
- 使用枚举类Enum作为callee和caller的约定,运用反射消除分支和重复代码在命令式程序中的应用
在开发过程中,程序提供的功能由简单变得复杂,承担功能的主要类也会因此变得庞大臃肿,如果不加以维护,就会散发出浓重的代码味道.下面这篇博文,主要讲述了利用Enum,反射等手段简化重构代码的过程. 代码涉 ...
- Java网络通信 —— 序列化问题
Java序列化的目的主要有两个: 1.网络传输 2.对象持久化 当选行远程跨迸程服务调用时,需要把被传输的Java对象编码为字节数组或者ByteBuffer对象.而当远程服务读取到ByteBuffer ...
- ftp被动模式下 ftp_put 上传文件
参考地址:https://blog.csdn.net/liuhelong12/article/details/50218311
- 初学 React native | 环境搭建(在模拟器上运行)
我的电脑是windows 所以就以 windows上+Android 配置React native 环境 网上的安装教程非常多,我总结了一下,配置环境时出错原因主要是node java python ...
- 【征文活动】为自己发“声” —— 声网RTC征文大赛在园子里征稿
2020年8月20日,声网Agora入驻园子的新楼盘--博客园品牌专区.9月,我们与声网Agora再度合作,「为自己发"声"- RTC 征文大赛」在园子里征稿. RTC(Real- ...