三层架构和MVC那点事儿
前言: 这是个老生常谈的话题了, 但我估计很多人还是会有疑惑, 我把自己的思考和大家分享下, 欢迎批评指正。
据说在上个世纪40年代, 有个叫IBM的公司宣称, 全世界只需要5台计算机就够了!
当时的人们肯定预料不到未来蓬勃发展的PC, 更想不到人们对计算有着多么大的需求。
那时候电脑是一个称为哑终端的东西, 这个东西可怜到只能用来发送、接收和显示字符, 不能安装程序, 没有复杂的交互, 即使是这样, 还只能是少数人有机会去使用。
但是,这个哑终端和一个无所不能的庞然大物相连接, 叫做“mainframe”, 这个怪兽掌管着所有的程序和数据。 这些哑终端就像是这个怪兽的触角而已, 离开了母体, 几乎没什么用处。
历史车轮滚滚向前, 从上世纪80年代开始, 个人计算机开始迅速的进入千家万户。
这些叫做PC的东西具备不错的计算能力,存储能力和显示能力, 完全不需要那个大怪兽就可以生存。
再加上局域网蓬勃发展, 大家马上想到, 能不能把Mainframe的部分功能移到PC上来?
这样既可以充分的利用资源, 又可以把Mainframe给弱化, 也许只用一个普通的服务器就能干活了。
想来想去, 数据库还是不能动, 还得要一个服务器来支持。
但是这业务逻辑,界面处理是不是可以放到客户端PC中来了? 于是就出了这么一个结构:
客户端的应用程序可不仅仅是显示字符了,它承担的任务很重, 要负责界面接口(我们常说的表示层逻辑), 业务逻辑, 还要负责和数据库服务器的通信, 有个很形象的词来称呼这些客户端应用程序: 胖客户端(fat client)。
这就是典型的两层(2-tier)架构, 在90年代风靡一时, VB, PowerBuilder, Delphi可以说是其中的代表, 这些工具都具备快速开发的能力, 通过拖拽控件到表单上, 很容易形成界面, 然后把控件和数据库的数据绑定就可以了。
客户端“变胖”是个进步,计算开始分布, 资源可以平衡, 但是这个架构也有几个缺点。
首先是每个客户端需要直接一个数据库连接, 发出查询, 显示数据。 由于客户端直接连接数据库,而数据库的连接又是非常宝贵的资源, 无法支持大量的客户端来访问,所以2-tier架构是用在局域当中的, 很难想象数据库暴露给海量的互联网用户直接访问。
其次业务逻辑和表示层逻辑绑在一起, 一旦业务逻辑有修改, 就意味着客户端的整个应用程序都要改一遍, 哪怕是修改了一点点业务逻辑, 那怕是这点逻辑对界面没有任何影响, 对不起, 请您重新发布, 测试,部署到所有的客户端吧。
所以把业务逻辑层和表示层分离开, 让各个部分各司其职,尽量独立,减少依赖成为了下一步的目标。
随着互联网的兴起, 尤其是应用服务器和中间件的出现, 业务逻辑找到了容身之所, 成功的和表示层逻辑分了家, 2-tier 迅速被 3-tier 架构所替代。
客户端的应用程序减肥成功, 只负责表示层逻辑(界面接口), 可以是一个独立的应用程序, 也可以是Web页面, 后者更加流行, 因为一个浏览器就可以工作了, 打开即用, 都不用安装。
那些不讲逻辑的业务逻辑被移到了服务器端, 可以尽情的修改, 只要不影响接口就行。
凡事都有利有弊, 分层要求某一层只能和自己的邻居打交道,不能跨层访问。
例如表示层不能绕过业务逻辑层直接访问数据库, 非得通过业务逻辑层不可。 数据在各层之间传来传去, 效率肯定有损失。
级联的修改也不可避免, 做过Web开发的应该深有体会, 客户说我们要在界面上加个新字段啊, 程序员把表示层改了当然不够, 业务层需要改, 数据库也得联动。
注意, 我之前提到层的时候,用的词都是Tier , 而不是Layer 。
虽然这两者经常互换使用, 但是确实有差别, 据Wikipedia定义, Tier 一般指的是物理的结构, layer 指的是逻辑结构, 举个例子, 一个3-layer的解决方案可以部署到一个tier上例如一个服务器。
现在我们把视线转向逻辑结构, 抛弃那些PC, 应用服务器, 数据库服务器 50 30131 50 15287 0 0 3478 0 0:00:08 0:00:04 0:00:04 3478 , 把3-tier 变成 3-layer 。
注意:从现在开始, 我们提到的层都是layer 了。
你看业务层和数据访问层是不是可以放到一个物理的服务器上的, 实际上我们也是这么做的:例如 Spring 可以认为是个业务层框架, Hibernate是个数据访问层的框架, 它们俩完全可以部署到一个应用服务器中(如Tomcat), 没有任何问题。
可能有人要问了, 我钟爱的Struts/Spring MVC 在哪儿? 这些MVC的实现框架实际上应该属于表示层, 至少是说C(Controller)和V(View)属于表示层:
当然这是一个非常简化的图, 现实会复杂的多的多, 例如:
1. 像Struts 有一个前端控制器(Front End Controller), 会把请求分发给一个个具体的Action 来处理。
2. 无论是Controller 还是Action, 通常不会直接访问Model, 而是访问一个叫做Service层的封装, 其中可以处理安全和事务。
3. View 通常不会直接访问Model , 也会封装一下 , 例如通过Helper类, ViewBean等等
......
可以看出,这些MVC框架实际上都是放在服务器端的, 它接收HTTP请求, 输出HTML+Javascript+CSS 到客户端机器, 在浏览器中运行起来 。
这里说的还是相对“传统”的架构, 现在新的趋势又开始形成, 那就是前后端分离, 服务器只剩下了业务层, 用于执行业务逻辑和提供接口, 表示层完全被移到了浏览器当中,那就是另外一个故事了。
(完)
你看到的只是冰山一角, 更多精彩文章,尽在“码农翻身” 微信公众号, 回复消息"m"或"目录" 查看更多文章
有心得想和大家分享? 欢迎投稿 ! 我的联系方式:微信:liuxinlehan QQ: 3340792577
公众号:码农翻身
“码农翻身”公众号由工作15年的前IBM架构师创建,分享编程和职场的经验教训。
掘金是一个高质量的技术社区,从 Swift 到 React Native,性能优化到开源类库,让你不错过互联网开发的每一个技术干货。长按图片二维码识别或者各大应用市场搜索「掘金」,技术干货尽在掌握中。