你能解释一下Context设计模式吗?

时间:2009-06-12 14:16:22

标签: design-patterns language-agnostic

我开始阅读有关Context design pattern的内容。以下是我从文中理解的内容:

  • 您有一张包含所有变量的地图

  • 您将它传递给任何需要它的人,这样您就不必将所有变量作为方法参数发送

我“得到”了吗?

4 个答案:

答案 0 :(得分:72)

  

我“得到”了吗?

不好意思说,不完全。

Context Object的目标是 not 隐式地将大量参数传递给方法,作为绕过强类型和封装的手段。目标是以一般但受管理的方式存储范围数据,而不依赖于协议和表示技术。存储在范围内的数据本质上是共享的,仍然可以是结构化的,并且与传递给方法的一次性参数本质上不同。

首先在Core J2EE Patterns 2nd Ed中引入了Context Object Pattern。 “上下文”部分指的是Object在范围的上下文中保存数据的事实 (例如application/session/request/conversation/flash)。

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

模式实施

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

Context Object 可以将数据存储在地图中,但它不需要 - 它可以以与程序相关的任何结构/格式存储数据。

应用程序可以为每个范围使用一个Context Object类,或者以有序的方式分割数据的几个类,避免过多的类膨胀并促进关注点的分离。

Context对象由最前面的表示类(Views,Front Controllers,Dispatchers)使用。这些表示客户端对象调用contextObject.get来检索存储的作用域数据,使用contextObject.put来存储作用域的上下文数据。

它不会传递到业务/集成逻辑中。它不能用作将大量参数传递给业务对象的方法,通过强类型输入。业务代表,应用程序服务和/或会话外观使用特定的强类型参数来构建业务和集成层。

模式优势

  • 可测试性:单元测试只需要模拟一个简单的POJO,而不是特定于协议的复杂服务器类,例如ServletContextHttpRequest
  • 灵活性&可重用性:应用程序的核心独立于类协议特定的“表示”层。这意味着应用程序可以更轻松地更改或添加协议或表示技术(例如HTML / HTTP / Servlet和WAP / Servlet以及XML / SOAP / HTTP / EJB和HTML / HTTP / JSF)。

<强>评论

  • 是历史模式
  • 有人可能会说依赖注入框架,例如CDI,Guice,Spring,Seam,&amp;其他人已经以与协议无关的方式实现了范围存储。即所有范围都已实现为上下文对象,这意味着开发人员不必再创建其他上下文对象。这并没有否定模式 - 这意味着CDI框架已经支持这种模式。
  • 如果执行不正确,最终可能会出现“在整个应用程序中传递巨大的上下文对象”反模式
  

引用KaptajnKold:   我想你明白了。   但是,我也认为这更像是一种需要避免的反模式。了解here

的原因

您的评论是指Context Object的错误实现版本。 Context Object本身不是反模式。

答案 1 :(得分:19)

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

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

  • globals
  • 单身人士
  • 长参数列表

The ACCU provides a more detailed description.

如果您想要在Java中使用上下文模式的真实示例,请查看Google Android API's

使用上下文模式时,您需要注意dependency graph。 (这就是KaptajnKold称之为反模式的原因。)

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

答案 2 :(得分:0)

使用上下文进行初始化的类。考虑一下这段代码

public class BuildTagHandler extends TagHandler {

      public BuildTagHandler(ServiceContext context) {  // constructor
            this.tagDAO = context.getTagDAO();
            this.buildDAO = context.getBuildDAO();
      }

您将使用上下文来构建您的课程。在上下文文件中,您没有实现,而是拥有大量这些DAO对象

您可以将其解释为外观模式,或者大型界面涵盖所有条目。

答案 3 :(得分:0)

上下文是一种反模式,因为它被用作先验未知的容器。