三层架构和 MVC 那点事儿

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