6

我刚开始使用dagger 2,之前没有使用过任何其他依赖注入框架。现在我陷入了循环依赖,我不知道如何正确解决它。考虑一个服务器应用程序中的以下示例,它使用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保存有关已连接客户端的一些状态。所有连接的客户端都在Server类中进行管理。

class Client {
  Handler h;

  public send(String response) {
    h.send(response);          
  }
}

当新的输入到达时,Handler 会创建Command对象,在服务器上执行它们,服务器最终会响应客户端。

所以我现在正在做的是Client手动创建一个对象Handler,传入一个this引用,以便能够发送响应:

client = new Client(this);

所以我现在的问题是:设计有问题吗?是否可以解耦ClientHandler?还是我应该忍受这个而不使用依赖注入everywhere

我很欣赏你的建议

4

2 回答 2

3

如果您希望客户端能够通过处理程序发回消息,那么以下内容可能会破坏您的循环:

// 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 来强调它是一种在包装器/接口上调用的不同方法,但当然你可以随意命名它们。

一句话:我没有使用 dagger2,所以我不能肯定地说我可以使用该产品完成我所做的事情,但这就是我如何解耦这种循环依赖

于 2015-01-28T12:45:43.877 回答
2

我意识到我真正想要解决的不是打破 and 之间的依赖关系ClientHandler而是使用依赖注入而不是new运算符。

我一直在寻找的解决方案:将 aClientFactory注入到构造函数中Handler并用于clientFactory.create(this)创建Client对象。出色的库AutoFactory@AutoFactory允许您使用简单的注释创建这样的工厂。创建的类的构造函数会自动用 注释@Inject

于 2015-01-29T14:59:27.500 回答