MVC似乎成为一个好的系统架构的代名词。很多人都在说我们将才实现中采用MVC模式,将业务逻辑和视图以及控制分开,以便日后的维护。
从接触到设计模式的那天起,脑海中就有了MVC的影子。并且试图在任何实现中将这个模式应用上去。但是始终没有完成一个自己满意的实现。关键就是C和M层。总觉得分的不是那么开。直到今天,才发现自己可能陷入了一个迷阵。
现在的Web开发流行使用Struts。Strus可以说是针对MVC一个很好的实现。JSP担任V,ActionBean担任C,M交给其他Javabean。但是就ActionBean是C还是M,好像也颇有争议。
其实对于Struts结构,我抱一种观望的态度。可能是我没有太深入的使用它,没有真正体味它的妙处。但是就我能够理解的实现看来。其关键思想就是将所有的操作定义了一个标签名,并且在配置文件里面为每一个标示名关联到一个Action上。Struts提供的机制截获所有的http请求,然后将符合过滤条件的请求进行分析,那么这些请求就是那些定义好的标签,其必然对应了一个Action,Struts机制就把这个请求推给这个ActionBean。剩下的事情就该怎么办就怎么办啦。完了之后再转向对应的JSP。采用Struts架构,给我的第一感觉就是多了一个配置文件的维护。但是它提供了一个很好的框架,帮助开发者来分开一些东西。
但是类似Struts这样的结构是不是MVC呢?
今天再次学习MVC模式。看到了一句话,这句话以前应该也看到了。但是可能一直没有注意到他的重要意义。模型-视图-控制器(Model-View-Controller,MVC)模式就是为那些需要为同样的数据提供多个视图的应用程序而设计的。看到这句话,突然醒悟,其实MVC并不是为了将显示、控制和业务逻辑分离而设计的。巧合的是MVC的提法和我们想象的吻合了。但是这样的设计或者叫做MCV更加合适一些。
视图一(表格) 视图二(饼图) 试图三(柱状图)
| | |
------------------------------------------------
|
数据模型
那么标准的MVC的各层任务应该是:控制层影响对象,模型层保存对象的状态,试图层将对象按照不同的形式进行展现。所以MVC应该只能解决数据的同一个拷贝按照不同的形式显示的问题。而不能解决我们要求的界面、控制、业务分离的问题。MVC解决了模型层的数据如何的被显示给用户,但是没有回答用户输入的数据怎么被提交给模型层。
按照原始的MVC的设计,C的控制应该不是提供业务流向的控制,而是可能引起模型变化的输入,比如说键盘、鼠标的输入,C的话应该是捕捉这些输入的程序实现。如果是这样,MVC模式的应用应该在需要将一份数据,而且这份数据在显示过程中可能动态改变的时候才是需要的。
但是将显示、控制以及业务分开的思想显然是很好的。将错就错的借用MVC的名字(或者叫做MCV),仔细再来分析各个层应该完成的任务。
V层。V直接和用户交互。包括将系统的信息以一定的方式展现给用户,或者提供录入接口,采集信息。
C层。就字面的理解,C就是控制。但是那些概念是属于控制的范畴呢?从一个页面转到另外一个页面(比如从用户信息管理页面到),算不算控制?请求完成一个用户信息的添加操作算不算控制?但是这两类控制显然属于不同的概念。前一类属于系统级别的控制请求,而后一类根接近业务逻辑。当然,我们可以抽象的认为这两类控制都是请求。控制层的任务就是按照请求规则来创建/提取对应的处理类。这里就需要映射表来完成请求和处理类之间的映射(如Struts的实现),但是这样做的实际效应到底有多大呢?
还有一个理解就是C不是负责这种消息的转发,而是完成系统访问的控制。比如针对不同的用户权限,在对同一个URL访问的时候,转向不同的处理。这样的话,似乎更加有意义。
M层。完成对业务数据的处理加工。
那么在很多时候,C层的引入可能并不是那么理想。而针对复杂的业务流程控制,或者引入专门的工作流引擎更加的实际。如果这样的话,我们实际只要考虑很好的分离V/M层就好了。