MVC和三层架构
看到坛子里有人讨论mvc,我也说说我对mvc的看法,顺带三层架构。
关于mvc的概念我就不多说了,mvc的应用很广,不仅仅在web开发中,swing就是基于mvc开发的一个GUI界面库,所以有人说mvc是观察者模式的一个变种,也没错,如果有开发过swing的同学们肯定能理解这个,swing中的事件处理就是观察者模式,但在web开发中的mvc 有点不同。GUI界面程序一般都是基于事件驱动的,而传统的web开发是基于请求响应的,现在也有基于事件驱动的web开发框架,比如JSF和ASP.NET。
基于事件驱动,这个很好理解观察者模式,组件注册动作监听器,有动作发生时,组件响应。这里面,组件是观察者,组件不依赖于动作的发生,动作的发生是未知的,组件不可能一直占用线程资源监测动作的发生。而有动作发生时,如果组件注册了对某个动作的监听器,那么组件就响应。关于这些,我改天重新开贴说明,此贴的重点不在这。
而对于基于请求响应的web开发,以J2EE开发为例,这里面Servlet就是一个观察者,servlet注册了对某一url的监听,当有属于自己监听的url请求时,servlet对这个请求进行响应。也就是说web开发本身就是一个观察者模式,只不过一般没人这么提罢了。
在说MVC之前,我们先说说三层架构,如果没有三层架构,那么我们的开发可以这样形容:一竿子通到底。 从参数的检测,业务逻辑的组装,数据库的访问都在一起,写着费劲,维护就更是噩梦了。慢慢的,你可能自己抽出一些类,其实也就是慢慢有了三层架构的雏形。三层架构:表现层,业务层,持久层。从字面意思你都能知道三个层各自的作用。业务逻辑清晰了,持久访问清晰了,表现层清晰了吗?依然没有。
在web开发中,尤其是现在的web开发,表现层不再是java程序员就能搞的定的,除非你是万金油。在多工种的合作开发中,我们需要这样一种思路:界面,控制器,模型分开开发。由控制器决定调用哪些模型完成业务,调用哪个界面显示。这似乎正是MVC。MVC只是表现层上的一种解决方案,不是一个项目的解决方案。总有人那电脑主机来比喻MVC,把CPU比做控制器,我不是说不能这么比,个人理解不一样嘛。但我们要知道,CPU不仅仅是资源调度这么简单,还有业务运算等更重要的事。
对于MVC,它从来也不是三个层,而是某一层的三个方面,在我的开发中,团队成员交流时,我直接限定不能说视图层,控制层,模型层,必须说视图,控制器,模型。可能有人会觉得这个很搞笑,但我们要注意,有些东西说的多了在心里就根深蒂固了,理解上也就有了不一样的意思了。
有人在坛子上说控制器越来越臃肿,为什么会臃肿,你把业务逻辑都写进控制器了能不臃肿吗?一个火车调度员还要负责怎么具体让信号设备正常显示,他不累么,动车能不出事吗?呵呵,说笑了,但我的意思很明确,控制器就是控制器,不是业务逻辑,控制器调用业务逻辑,而不是实现业务逻辑。
对于MVC中的模型,就是业务逻辑的组合,我曾被人误导理解成和数据持久一样的东西,导致我的控制器就只能是业务逻辑了。模型就是对某一事物的解决方案,它由很多逻辑组成,而某些逻辑还有数据持久等。
我们以jsp+servlet+javabean开发为例说明下:
曾几何是,jsp是视图,servlet是控制器,javabean是模型,这种说法不管是书中还是网络上都大有文章,我这里不是说这是错误的,而是个人理解的角度不一样。 站在项目的角度上,控制器是谁,是web.xml,为什么,因为你的url映射是在web.xml中,由web.xml决定调用那个servlet,(自定义映射关系的不算)而此时的servlet充当的正是模型的角色,因为是它在组合业务逻辑,但同时,servlet也充当控制器,因为由它来决定显示按个视图,关系是不是有点复杂啊。
站在业务逻辑的角度上,控制器是servlet,因为servlet决定调用那个业务逻辑,显示那个视图。此时的模型是谁呢?这要看代码的写法了,如果你把解决此次访问的业务逻辑放在一个类中,那么这个类就是模型,servlet控制器只要调用这个类就行了; 如果你把这些业务逻辑放在servlet的service()方法中,那么此时的servlet也充当了模型的角色。
使用表现层的一些框架,有助于我们加深对MVC的理解,以Struts1为例,dispatchAction充当了控制器的角色,具体看struts-config就能得知,dispatchAction对请求进行分发,并负责响应的视图显示,而你的action正是模型,分发的请求由相应的action模型来处理。