【发布时间】:2012-12-12 19:56:24
【问题描述】:
我们正准备开始在我们的保险数据转换平台中使用 Guice,我遇到了一个有趣的场景,在 Guice 文档或我找到的任何帖子中似乎都没有直接解决。
我们的平台在几个重要领域使用封装上下文 (EC) 模式。例如,假设我们正在处理一组 10 个策略。每当我们开始处理新策略时,我们希望构造一个PolicyContext 对象并初始化诸如策略编号、状态和公司之类的属性。这个PolicyContext 是转换过程中涉及的许多类的依赖项。
请注意,PolicyContext(以及我们应用程序中的其他 *Context 对象)是一个紧密关注特定域领域的值对象(代表基本的、普遍需要的策略信息)。我很想知道你们中的模式专家是否仍然认为这是一种反模式(正如 Misko Hevery 在http://misko.hevery.com/2008/07/18/breaking-the-law-of-demeter-is-like-looking-for-a-needle-in-the-haystack/ 中所讨论的那样),即使这些是纯粹的价值对象并且当然不代表“厨房水槽”。 ”
目前,我们以最糟糕的方式管理PolicyContext:我们有一个静态全局变量policyContext,并且每当我们开始处理新策略时都会调用policyContext.initialize(String company, String state, String policyNum)。
我的目标是让 Guice 以架构上优化的方式管理这些上下文对象,以便从概念上讲,每当我们开始处理新策略时:
- Guice 丢弃了旧的
PolicyContext。 - Guice 使用来自数据库的
company/state/policyNum参数构造了一个新的、不可变的PolicyContext(无异味初始化方法)。 - Guice 将已经构造的
PolicyContext注入到所有需要它的类中。
这是我的初步方法:
- 创建自定义范围——类似于http://code.google.com/p/google-guice/wiki/CustomScopes 的 Guice 批处理范围示例——其中批处理的边界由外部确定。有了这个范围,我们开始处理一个新的策略,我们可以 1) 结束前一个“批次”并开始一个新的。 问:我为什么不能完全按照上述 URL 中列出的方式使用 Guice 批处理范围示例?
-
由于
PolicyContext没有依赖关系,我们将对所有 构造函数参数使用AssistedInject(这似乎有点奇怪)。假设我们采用这种方法并生成一个PolicyContextFactory,那么我们开始处理新策略的地方就会有如下代码:… scope.exit(); scope.enter(); @Inject private PolicyContextFactory policyContextFactory; policyContextFactory.create(company, state, policyNum); // the parameters come from a database record. // Note that we don’t need to actually store the created instance; it will be injected elsewhere into various class constructors. …
这看起来是最优的吗?我知道可能有更简单的方法(例如,每当我们处理新策略时,创建一个新的PolicyContext 特定注入器,这实际上会创建一个新的PolicyContext)。然而,这是架构的核心方面,所以我真的不想妥协。
我知道,另一种选择是在这种情况下避免使用 DI,而只使用具有单独 create 和 get 方法的静态 PolicyContextManager 类,其中前一种方法是丢弃当前的工厂PolicyContext 并创建/存储一个新的,而后一种方法只返回“活动”PolicyContext)。但是我的代码最终会做手动 DI,因为我会写很多像methodThatNeedsPolicyContext(PolicyContextManager.get(), …) 这样的代码。由于我们无论如何都打算开始使用 Guice,所以这种方法似乎不是最优的。
顺便说一句,对于那些试图深入了解 DI 的人,我强烈推荐 Dhanji Prasanna 的“依赖注入”。这本书侧重于 Guice 和 Spring,绝对是必不可少的,因为它比我遇到的任何其他书都深入得多。
感谢您的帮助!
【问题讨论】: