问题描述
我已经开始阅读有关上下文设计模式.这是我从文本中了解的:
-
您有一个包含所有变量的地图
-
您将其传递给需要它的任何人,因此您不必将所有变量作为方法参数发送
我"得到"了吗?
推荐答案
我是否"获取"它?
很抱歉说,不完全.
上下文对象的目标是不是将大量参数隐含地传递给方法,以此作为通过强大的键入和封装的一种手段.目的是以一般但管理的方式存储范围的数据,独立于协议和演示技术.存储在范围内的数据本质上是共享的,仍然可以结构化,并且与传递给方法的一次性参数固有不同.
.上下文对象模式首先在 core j2ee模式下ed . "上下文"部分是指该对象在范围
上下文中保存数据的事实
(例如application/session/request/conversation/flash).
它的目的是尽可能地将应用程序数据和逻辑从协议/呈现技术 - 特定类别(例如HttpSession>>>>>>)分发.
模式实现
在上下文对象下,用于应用程序/会话/请求/其他范围的数据未直接放入ServletContext/HttpSession/HttpRequest/其他特定于协议的类中.相反,数据存储在POJO包装类中,然后位于ServletRequest/HttpSession/HttpRequest/其他中.
上下文对象可能将数据存储在地图中,但不需要 - 它可以将数据存储在与程序相关的任何结构/格式中.
一个应用程序可以每个范围使用一个上下文对象类,或以有序的方式分割数据,避免过度的类膨胀并促进关注点的分离.
上下文对象由最初的演示文稿类(视图,前控制器,调度程序)使用.这些演示端对象调用ContextObject.
它没有传递到业务/集成逻辑中.它不被用作通过强大的打字来将多种参数传递给业务对象的一种手段.业务和集成层由业务代表,应用程序服务和/或会话外墙的领导者面前.
模式益处
- 可检验性:单元测试只需要模拟简单的POJO,而不是特定于协议的复杂服务器类,例如ServletContext或HttpRequest
- 灵活性和可重复性:应用程序的核心独立于类别的类别的"表现"类层.这意味着应用程序可以更轻松地更改或添加协议或演示技术(例如HTML/HTTP/Servlet和WAP/Servlet以及XML/SOAP/HTTP/EJB和HTML/HTML/HTTP/JSF).
评论
- 是一种历史模式
- 可以说,依赖性注入框架,例如CDI,GUICE,SPRING,SEAM和其他框架,提供了已经以与协议无关的方式实现的范围存储.即,所有范围都已实现为上下文对象,这意味着开发人员不太强迫创建其他上下文对象.这不会否定模式 - 这意味着CDI框架已经支持该模式.
- 如果错误地实现,则可以最终以"围绕整个应用程序中的巨大上下文对象传递",抗pattern
引用kaptajnkold: 我想你明白了. 但是,我也认为这更像是一种反塔.请参阅为什么在这里..
您的评论是指上下文对象的模拟版本.上下文对象本身不是反pates.
其他推荐答案
上下文对象提供对共享数据和功能的访问.
它可以是:
的优雅而灵活的替代品- Globals
- 单身人士
- 长参数列表
如果您想要Java中上下文模式的真实示例,请检查 google android api .
您需要注意依赖关系图使用上下文模式时. (这就是Kaptajnkold称其为反模式的原因.)
要限制不必要的依赖性,请使用不同的上下文来实现不同的目的.使您的上下文尽可能简单,并在需要时使用构图或继承来增加复杂性.
其他推荐答案
使用上下文inialize的类.考虑此代码
public class BuildTagHandler extends TagHandler { public BuildTagHandler(ServiceContext context) { // constructor this.tagDAO = context.getTagDAO(); this.buildDAO = context.getBuildDAO(); }
您将使用上下文来构建课程.在上下文文件中,您将没有实现,而是拥有很多这些DAO对象
您可以将其解释为立面模式,或者一个巨大的界面覆盖所有条目.
问题描述
I've started to read about the Context design pattern. Here's what I understood from the text :
you have a map containing all your variables
you pass it around to whoever needs it, so that you won't have to send all the variables as method parameters
Did I "get" it?
推荐答案
Did I "get" it?
Sorry to say, not quite.
The goal of Context Object is not to pass lots of parameters to methods implicitly, as a means of by-passing strong typing and encapsulation. The goal is to store scoped data in a general, but managed way, independent of protocols and presentation technology. Data stored within a scope is by nature shared, can still be structured, and is inherently different than one-off parameters passed to a method.
Context Object Pattern was first introduced in the Core J2EE Patterns 2nd Ed. The 'Context' part refers to the fact that the Object holds data in the Context of a scope
(such as application/session/request/conversation/flash).
Its purpose is to decouple, as much as possible, application data and logic from protocol/presentation-technology- specific classes such as HttpSession and HttpRequest.
Pattern Implementation
Under Context Object, data intended for application/session/request/other scope is not put directly into ServletContext/HttpSession/HttpRequest/other protocol-specific class. Instead, the data is stored in a POJO wrapper class, that then sits in the ServletRequest/HttpSession/HttpRequest/other.
The Context Object may store the data in a map, but it doesn't need to - it can store the data in any structure/format relevant to the program.
An application may use one Context Object class per scope, or several classes which split the data in an orderly fashion, avoiding excessive Class bloat and promoting separation of concerns.
The Context Object is used by the frontmost presentation classes (Views, Front Controllers, Dispatchers). These presentation client objects call contextObject.get to retrieve stored scoped data and contextObject.put to store scoped context data.
It is not passed into business/integration logic. It is not used as a means of passing a multitude of parameters into business objects, by-passing strong typing. The Business and Integration Tiers are fronted by Business Delegates, Application Services and/or Session Facades which use specific strongly-typed parameters.
Pattern Benefits
- Testability: Unit tests only need to mock a simple POJO, rather than a protocol-specific complex server class, such as ServletContext or HttpRequest
- Flexibility & Reusability: The core of the application works independently of the thin protocol-specific 'presentation' layer of classes. This means that an application can more easily change or add protocols or presentation technology (e.g. HTML/HTTP/Servlet and WAP/Servlet and XML/SOAP/HTTP/EJB and HTML/HTTP/JSF).
Comments
- Is an historical pattern
- One could argue that dependency injection frameworks, such as CDI, Guice, Spring, Seam, & others give scope storage already implemented in a protocol-independent way. i.e. that all of the scopes are implemented as Context Objects already, meaning that the developer is less compelled to create additional Context Objects. That doesn't negate the pattern - it means the CDI framework already supports the pattern.
- If incorrectly implemented, one can end up with the "Pass Around Ginormous Context Objects Throughout The Application" anti-pattern
Quoting KaptajnKold: I think you got it. However, I also think it is more of an anti-pattern to be avoided. See why here.
Your comments refer to the misimplemented version of Context Object. Context Object itself is not an anti-pattern.
其他推荐答案
A context object provides access to shared data and functions.
It can be an elegant and flexible substitute for:
- globals
- singletons
- long parameter lists
The ACCU provides a more detailed description.
If you want a real world example of the context pattern in Java, check the Google Android API's.
You need to be mindful of your dependency graph when using the context pattern. (This is the reason KaptajnKold calls it an anti-pattern.)
To limit unnecessary dependencies, use different contexts for different purposes. Keep your contexts as simple as possible and use composition or inheritance to add complexity when needed.
其他推荐答案
A class using context to inialize. Consider this code
public class BuildTagHandler extends TagHandler { public BuildTagHandler(ServiceContext context) { // constructor this.tagDAO = context.getTagDAO(); this.buildDAO = context.getBuildDAO(); }
You'll use context to construct your class. In context file, you'll not have implementations, instead you have a whole lot of these DAO objects
You can interpretate it as a facade pattern, or a huge interface covers all entries.