你能解释一下Contextdevise模式吗?

我已经开始阅读关于Contextdevise模式 。 以下是我从文中理解的内容:

  • 你有一个包含所有variables的地图

  • 你把它传递给需要它的人,这样你就不必把所有的variables都作为方法参数发送出去

我“得到”了吗?

我想你明白了。

但是,我也认为这是一个更应该避免的反模式。 看看这里为什么。

也参见得墨忒耳法

我“得到”了吗?

对不起,说不完。

上下文对象的目标不是将大量的参数隐式地传递给方法,作为绕过强打字和封装的手段。 其目标是以范围广泛的pipe理方式存储范围内的数据,而不依赖于协议和表示技术。 存储在范围内的数据本质上是共享的,仍然可以是结构化的,并且本质上不同于传递给方法的一次性参数。

上下文对象模式是在Core J2EE Patterns 2nd Ed中首次引入的。 “上下文”部分是指对象在范围的上下文中保存数据的事实
(如application/session/request/conversation/flash )。

它的目的是尽可能地从协议/表示技术特定的类(如HttpSessionHttpRequest )中分离应用程序数据和逻辑。

模式实施

在上下文对象下,用于应用程序/会话/请求/其他范围的数据不直接放入ServletContext / HttpSession / HttpRequest /其他协议特定的类中。 相反,数据存储在POJO包装类中,然后位于ServletRequest / HttpSession / HttpRequest / other中。

上下文对象可以将数据存储在地图中,但不需要 – 它可以以与程序相关的任何结构/格式存储数据。

一个应用程序可以使用每个范围的一个Context对象类,或者有序地分割数据的几个类,避免过度的Class膨胀和促进关注的分离。

上下文对象由最前面的表示类(视图,前端控制器,分派器)使用。 这些表示客户端对象调用contextObject.get来检索存储的作用域数据,contextObject.put来存储作用域上下文数据。

它不被传入业务/集成逻辑。 它不被用作将大量parameter passing到业务对象的方式,绕过强大的input。 业务和集成层面由业务代表,应用服务和/或会话外观使用特定的强types参数。

模式的好处

  • 可testing性:unit testing只需要模拟一个简单的POJO,而不是一个协议特定的复杂服务器类,比如ServletContext或者HttpRequest
  • 灵活性和可重用性:应用程序的核心工作独立于瘦协议特定的“表示”类层。 这意味着应用程序可以更容易地更改或添加协议或表示技术(例如HTML / HTTP / Servlet和WAP / Servlet和XML / SOAP / HTTP / EJB和HTML / HTTP / JSF)。

注释

  • 是一种历史模式
  • 有人可能会争辩说,dependency injection框架,如CDI,Guice,Spring,Seam和其他人给范围存储已经以独立于协议的方式实现。 即所有的范围已经被实现为上下文对象,这意味着开发者不需要创build额外的上下文对象。 这并不否定这种模式 – 这意味着CDI框架已经支持这种模式。
  • 如果实施不当,最终可能会出现“遍历应用程序中的多重上下文对象”反模式

引用KaptajnKold:我想你明白了。 但是,我也认为这是一个更应该避免的反模式。 看看这里为什么。

您的评论指的是上下文对象的错误实现版本。 上下文对象本身不是反模式。

上下文对象提供对共享数据和函数的访问。

它可以是一个优雅和灵活的替代品:

  • 全局
  • 单身
  • 长参数列表

ACCU提供了更详细的描述。

如果您想要Java中的上下文模式的真实世界示例,请查看Google Android API 。

在使用上下文模式时,您需要注意您的依赖关系图 。 (这就是KaptajnKold把它称为反模式的原因。)

为了限制不必要的依赖性,可以为不同的目的使用不同的上下文 保持您的上下文尽可能简单,并在需要时使用组合或inheritance来增加复杂性。