日期:2014-05-19  浏览次数:20703 次

J2EE表现层模式--context对象
问题:

不想在协议无关的环境上下文中使用针对特定协议的系统信息。

   在请求和响应的整个生命周期中,一个应用系统通常要使用系统信息,比如请求、配置、安全数据等等。系统信息的获取方式与环境的上下文相关。当负责业务应用的组件和服务必须使用一些处于他们环境上下文之外的系统信息时,这些组件的灵活性和可重用性都会下降。所以,在相关的环境上下文之外使用一个特定协议的API,这就会把特定的就接口和处理细节暴露给使用这个API的所有组件。这样,所有作为API的客户的组件也就和那个特定的协议产生了紧耦合。

   比如说,web组件接受HTTP协议的请求。但是,如果让表现层和其他层次的组件共享这些HTTP请求,这就会吧协议的细节暴露给所有这样的组件。如果协议本身或者其中某个细节改变了,比如说,如果表单的某个元素或者字段名称变了;那么所有的客户端代码也必须变化。

约束:

--组件和服务要访问系统信息

--要解除系统信息的协议细节与业务应用组件/服务之间的耦合

--只想在特定的环境上下文中暴露与协议先关的API

解决方案:

   使用Context对象,按照协议无关的方式封装状态,然后在整个应用系统中使用这种封装后的对象。

   用Context对象封装系统数据,就可以让应用系统的其他部分也能使用这样的数据,同时也不避免在应用系统和特定的协议之间造成耦合。

   比如,HTML表单中的每个字段对应于HTTP请求中的一个参数;context对象可以按照协议无关的方式存储这种数据,同时也便于数据的转换和验证。应用系统的其他部分可以直接通过这个context对象来访问这些数据,并不需要HTTP协议有任何知识。如果协议发生了任何变化,都可以交给这个Context对象处理,系统的其他部分无需改动。

    既然减少了对特定协议的依赖,那么也就更加方便测试,很容易在一种更加通用的环境下进行测试,减少了对特定的容器的依赖,比如,可以用Context对象包装HttpServletRequest,这样就可以在web容器之外轻松地使用这个Context对象进行测试。为了满足需要,可以让这个Context对象装载假数据,而无需包含HttpSerlvetRequest对象,使用了Context对象,还能将状态抽象出来,形成在不同层次间共享的数据结构,从而有助于对业务层隐藏表现层的实现细节。Context对象对于协议是中立的,它所提供的松耦合特性能够增进应用系统的可重用性和可维护性。

    使用了Context对象,就引发了传输对象之间的关系的问题。传输对象在远程的层次之间传输状态。虽然在传输数据的目的上,Context对象和传输对象的目的一致,但是Context对象共享的还是系统的数据,从而增进应用系统的可重用性和可维护性。

   通过这种方式,Context对象减少了原本不相关的系统组件和业务应用组件之间的耦合。传输对象往往封装的是业务数据,而Context对象体现的则是底层状态。