打破循环依赖以使用依赖注入
Break cyclic dependency in order to use dependency injection
我刚开始使用 dagger 2 and have not used any other dependency injection framework before. Now I'm stuck with a cyclic dependency and I don't know how to solve it properly. Consider the following example in a server application, which uses the Reactor pattern 和 Java NIO:
我有一个 Handler
对象附加到选择键,当新信息到达网络时执行:
class Handler implements Runnable {
Server server;
Client client;
public void run {
// static factory method that eventually calls a method on server, passing in 'client' as argument
Command.parse(input).execute(server, client);
}
public void send(String string) {
// enqueu string and inform reactor about interest in sending
}
}
Client
class 保存有关已连接客户端的一些状态。所有连接的客户端都在 Server
class.
中管理
class Client {
Handler h;
public send(String response) {
h.send(response);
}
}
当新的输入到达时,处理程序创建Command
对象,在服务器上执行它们,服务器最终会响应客户端。
所以我现在正在做的是在 Handler
中手动创建一个 Client
对象,传入 this
引用,以便能够发送响应:
client = new Client(this);
所以我现在的问题是:设计有问题吗?是否可以将 Client
和 Handler
解耦?或者我应该忍受这个而不使用依赖注入 everywhere
?
感谢您的建议
如果您希望客户端能够通过处理程序发回消息,那么以下可以打破您的循环:
// lives in a common package both classes access
public interface ResponseClass {
public void sendSomeMessage(String message);
}
public class Handler { // handler can also implement ResponseClass directly but I prefer using an additional class for flexibility.
public void whenYouCreateClient() {
Client client = new Client(new HandlerWrapper(this));
}
public static class HandlerWrapper implements ResponseClass {
private final Handler handler;
public HandlerWrapper(Handler handler) { this.handler = handler; }
public void sendSomeMessage(String message) {
handler.send(message);
}
}
public void send(String string) {
// enqueu string and inform reactor about interest in sending
}
}
public class Client {
ResponseClass rc; // naming should be improved :)
public void sendMessage(String message) {
rc.sendSomeMessage(message);
}
}
现在运行时,您的 类 仍然捆绑在一起,但就您的设计而言,您的客户端仅附加到通用 ResponseClass。
你可以有这样的层次结构:
通用 <-- 客户端 <-- 处理程序
处理程序知道客户端和通用的位置
而客户只知道共同点。 (假设你把接口放在common包里)
而不是
客户端 <--> 处理程序
我特意使用 sendSomeMessage 来强调它是您在 wrapper/interface 上调用的另一种方法,但您当然可以随意命名它们。
一句话:我没有使用 dagger2,所以我不能肯定地说我所做的可以使用那个产品来完成,但这就是我解耦这种循环依赖的方式
我意识到我真正想解决的不是打破Client
和Handler
之间的依赖关系,而是使用依赖注入而不是new
运算符。
我正在寻找的解决方案:将 ClientFactory
注入到 Handler
的构造函数中,然后使用 clientFactory.create(this)
创建一个 Client
对象。出色的库 AutoFactory 允许您使用简单的 @AutoFactory
注释创建这样的工厂。创建的class的构造函数会自动注解为@Inject
.
我刚开始使用 dagger 2 and have not used any other dependency injection framework before. Now I'm stuck with a cyclic dependency and I don't know how to solve it properly. Consider the following example in a server application, which uses the Reactor pattern 和 Java NIO:
我有一个 Handler
对象附加到选择键,当新信息到达网络时执行:
class Handler implements Runnable {
Server server;
Client client;
public void run {
// static factory method that eventually calls a method on server, passing in 'client' as argument
Command.parse(input).execute(server, client);
}
public void send(String string) {
// enqueu string and inform reactor about interest in sending
}
}
Client
class 保存有关已连接客户端的一些状态。所有连接的客户端都在 Server
class.
class Client {
Handler h;
public send(String response) {
h.send(response);
}
}
当新的输入到达时,处理程序创建Command
对象,在服务器上执行它们,服务器最终会响应客户端。
所以我现在正在做的是在 Handler
中手动创建一个 Client
对象,传入 this
引用,以便能够发送响应:
client = new Client(this);
所以我现在的问题是:设计有问题吗?是否可以将 Client
和 Handler
解耦?或者我应该忍受这个而不使用依赖注入 everywhere
?
感谢您的建议
如果您希望客户端能够通过处理程序发回消息,那么以下可以打破您的循环:
// lives in a common package both classes access
public interface ResponseClass {
public void sendSomeMessage(String message);
}
public class Handler { // handler can also implement ResponseClass directly but I prefer using an additional class for flexibility.
public void whenYouCreateClient() {
Client client = new Client(new HandlerWrapper(this));
}
public static class HandlerWrapper implements ResponseClass {
private final Handler handler;
public HandlerWrapper(Handler handler) { this.handler = handler; }
public void sendSomeMessage(String message) {
handler.send(message);
}
}
public void send(String string) {
// enqueu string and inform reactor about interest in sending
}
}
public class Client {
ResponseClass rc; // naming should be improved :)
public void sendMessage(String message) {
rc.sendSomeMessage(message);
}
}
现在运行时,您的 类 仍然捆绑在一起,但就您的设计而言,您的客户端仅附加到通用 ResponseClass。
你可以有这样的层次结构:
通用 <-- 客户端 <-- 处理程序
处理程序知道客户端和通用的位置 而客户只知道共同点。 (假设你把接口放在common包里)
而不是 客户端 <--> 处理程序
我特意使用 sendSomeMessage 来强调它是您在 wrapper/interface 上调用的另一种方法,但您当然可以随意命名它们。
一句话:我没有使用 dagger2,所以我不能肯定地说我所做的可以使用那个产品来完成,但这就是我解耦这种循环依赖的方式
我意识到我真正想解决的不是打破Client
和Handler
之间的依赖关系,而是使用依赖注入而不是new
运算符。
我正在寻找的解决方案:将 ClientFactory
注入到 Handler
的构造函数中,然后使用 clientFactory.create(this)
创建一个 Client
对象。出色的库 AutoFactory 允许您使用简单的 @AutoFactory
注释创建这样的工厂。创建的class的构造函数会自动注解为@Inject
.