复合视图:Composite View。使用由多个原子化的子视图构成的复合视图。特点是组合是可以动态的,而页面布局又可以整体控制,和页面内容互相独立。
有这么几个常见的例子:Portlet就是一个复合视图结合的最好例子,主题可以影响到所有视图的呈现,又是和展示的具体内容没有关系的,Portlet可以在服务端做到视图的聚合,而不把事情遗留到客户端完成,不涉及浏览器跨域的安全性问题;SiteMesh是一个很适合对页眉、页脚等页面通用元素拼装的框架,比jsp:include标签优雅;更小维度上,标签的引用也可以认为是视图的复合。
视图的复合增进了视图模块化和重用能力,这方面来看是增加了可维护能力;但是另一方面,一个完整的直观的页面被拆得七零八落,又降低了可维护性,为了解决这个问题,我觉得对于一个大型Web应用,一个好的思路是提供一种工具,至少是一个简易的指导方法,从页面的某一部分元素快速定位到具体的最小视图上;另外,视图的复合带来了服务端拆解和部署的灵活性,但一定也带来性能损耗,Portlet聚合尤为明显。
还有一个重要的事项是,页面布局需要和页面内容相独立。一个较大的视图拆解成若干个小的子视图,这些小的子视图应当具备独立的展示内容,但是页面的布局不应当有其中的任一子视图控制,而可以落到某一个整体的主题定义中去。
服务到工作者:Service To Worker。集中控制权管理和请求的处理,再把控制权交给视图之前获取表现模型。视图则根据获得的表现模型生成一个动态响应。这个模式是由前端控制器、应用控制器和视图助手组合而成的。具体说:前端控制器集中了访问视图的逻辑,然后应用控制器完成了视图导航,最后由视图助手协助准备了视图所使用的模型数据。
分配器视图:Dispatcher View。把视图本身作为请求的最初访问点,把业务处理的逻辑交由视图完成。
服务到工作者和分配器视图是非常类似的两种模式,前者以进视图前的逻辑处理为核心,后者才真正以视图为核心。当业务处理比较简单,或者不能合适地通过视图之外的逻辑来控制时,可以采用分配器视图模式,把控制逻辑放到视图中。在这种方式下,不代表分配器视图做了所有的业务逻辑,对于数据的准备完全可以在进视图之前完成,毕竟视图中完成大量的业务逻辑通常不是一个优秀的解决方案。
一个很好的例子就是页面集成,进入集成页之前准备好集成的子页面的URL,到了集成的父页面中再执行拼装操作,这个行为,甚至可能被到客户端才完成。这种情形下,尽管页面去做了聚合视图的事,但这恰恰是页面最擅长的行为,比进页面之前把数据准备好、拼装好再一并写入页面要可见和可接受得多。