我有一个使用CQRS和依赖注入的项目。系统的查询端很好。
对于系统的命令端,我选择使用队列:
BlockingQueue<Command> commandQueue;
这将存储接收到的命令及其来自多个线程的参数。这些命令都实现了一个带有execute方法的通用接口:
public interface Command extends Serializable {
void execute();
}
命令的参数作为数据存储在Command接口的具体实现中。参数的类型和可能数量将根据它所代表的命令而有所不同,使用此结构意味着此详细信息全部封装在远离命令队列逻辑的位置。
这个想法是命令稍后由工作线程按顺序执行,工作线程依次调用每个Command上的execute(),而不关心它在哪个命令下。
这些命令只有在准备好执行的队列中才需要注入(这主要是因为我希望能够序列化命令,但也因为命令的执行需要不同的模块到应用程序的一部分接收并排队他们)
我的问题是: 因为命令需要等到它们从队列中取出才能获得它们的依赖关系,所以我最终将一个轻微包装的Injector传递给它们的'execute'方法,这样它们就可以自己创建一个对象图。这比服务定位器模式更像是依赖注入。
public interface Command extends Serializable {
void execute(**ExecutorLocator locator**);
}
我是否缺少某些东西,或者DI必须在堆栈中的某个位置看起来像服务定位器一样?
答案 0 :(得分:2)
自从我把手放在Java代码上已经有一段时间了,但良好的架构和设计并没有绑定语言。
首先:ServiceLocator is an anti-pattern。
第二:Tell, don't ask。如果有什么东西从外部构建命令,并且不让它们向定位器询问它们的依赖性。
第三:我将创建为命令注册的处理程序,并知道如何处理命令中封装的信息。因此,您根本不需要注入或构建命令。设置处理程序并确保命令到达那里。