我有一个正在使用 CQRS 和依赖注入(inject)的项目。系统的查询端很好。
对于系统的命令端,我选择使用队列:
BlockingQueue<Command> commandQueue;
这会存储从多个线程接收到的命令及其参数。这些命令都通过执行方法实现了一个公共(public)接口(interface):
public interface Command extends Serializable {
void execute();
}
命令的参数作为数据存储在命令接口(interface)的具体实现中。参数的类型和潜在数量将根据它代表的命令而变化,使用此结构意味着此细节全部封装在命令队列逻辑之外。
这个想法是,这些命令稍后由工作线程按顺序执行,该线程依次对每个命令调用execute(),而不关心它在幕后是哪个命令。
这些命令仅在从准备执行的队列中取出后才需要注入(inject)(这主要是因为我希望能够序列化命令,但也因为命令的执行需要与应用程序的部分不同的模块)接收并排队它们)我的问题是这样的: 因为命令需要等到它们从队列中取出才能获取它们的依赖项,所以我最终将一个轻包装的注入(inject)器传递给它们的“执行”方法,以便它们可以为自己创建一个对象图。这感觉更像是服务定位器模式而不是依赖注入(inject)。
public interface Command extends Serializable {
void execute(**ExecutorLocator locator**);
}
我是否遗漏了什么,或者 DI 不可避免地必须在堆栈中的某个点看起来像服务定位器?
最佳答案
自从我接触 Java 代码以来已经有一段时间了,但良好的架构和设计并不局限于某种语言。
第一:ServiceLocator is an anti-pattern .
第二个:Tell, don't ask 。如果有任何东西从外部构建命令,并且不要让它们向定位器询问其依赖项。
第三:我将创建为命令注册的处理程序,并知道如何处理命令中封装的信息。因此,您根本不需要注入(inject)或构建命令。设置您的处理程序并确保您的命令到达那里。
关于java - 命令队列引导代码看起来像服务定位器模式而不是依赖注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11897643/