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

Geo*_*Geo 48 language-agnostic design-patterns

我开始阅读有关Context设计模式的内容.这是我从文中理解的内容:

  • 你有一个包含所有变量的地图

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

我得到了吗?

Gle*_*est 72

我得到了吗?

对不起,不太好说.

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

Context Object Pattern最初是在Core J2EE Patterns 2nd Ed中引入的."上下文"部分指的是Object在范围 的上下文
(例如application/session/request/conversation/flash)中保存数据的事实.

其目的是尽可能地将协议/表示技术特定类(如HttpSession和)的应用程序数据和逻辑去耦HttpRequest.

模式实施

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

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等,已经以与协议无关的方式实现了范围存储.即所有作用域都已实现为Context Objects,这意味着开发人员不必再创建其他Context对象.这并没有否定模式 - 这意味着CDI框架已经支持这种模式.
  • 如果执行不正确,最终可能会出现"在整个应用程序中传递巨大的上下文对象"反模式

引用KaptajnKold:我想你明白了.但是,我也认为这更像是一种需要避免的反模式.为什么在这里.

您的评论引用了Context Object的错误实现版本.Context Object本身不是反模式.

  • 让我想起了Win 32 API,你为一个方法调用创建了一个巨大的对象,并将其作为参数传递,IMO是一个反模式.许多属性仅与单个方法调用相关,即窗口的窗口大小和位置.上下文对象的属性不应该如此短暂,并且在当前范围内应该是相关的和通用的.某些属性(如root /父窗口)将是有效的上下文信息.希望这有助于人们思考和评估他们是否滥用这种模式.这肯定不是一门精确的科学. (2认同)

Sha*_*ley 20

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

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

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

ACCU提供更详细的描述.

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

使用上下文模式时,需要注意依赖图.(这就是KaptajnKold称之为反模式的原因.)

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