在Design Patterns: Elements of Reusable Object-Oriented Software一书中,作者以smalltalk MVC为例,赞扬了通知/订阅者(notify/subscribe)协议和观察者(Observer)模式的使用。其中局的一个经典的例子是对同一数据,系统可能需要不同的显示视图,比如条形图、饼图、数据表格等等,如下图:
在Model1模式的web编程中,Model部分可以交给EJB及JDBC实现,而View部分可以由Jsp完成,但是却没有合适的工具完成独立的Contrroller。在Model2的思想提出由Servlet应付控制流,在Struts中Servlet就扮演了Front End Controller的角色。
当客户端提出请求,ActionServlet响应请求,并且在指定的Struts-Config.xml文件中查到请求对应的Action(Action是Struts引入的一个核心类,作为Back End Controller,在后文会介绍),对已经实例化的Action,ActionServlet为这个新的请求开一个线程,对未实例化的Action,ActionServlet将其实例化。
Action作为Back End Controller可以与Model部分交互,以实现状态改变或者状态查询,Action还将返回下一步的视图选择给ActionServlet。ActionServlet根据对应的Struts-Config.xml找到视图选择对应物理地址,并把新的View返回给用户端。
图4 Struts实现层模式的MVC结构
另一种常见的关于Srtuts实现MVC模式的看法是认为只有ActionServlet是Controller,而把Action看作BusinessLogic。我认为,这种看法是没有前一种将Action视为Back End Controller的看法合理的,因为Controller部分需要完成的视图选择实际上是由Action实现的。