打破循环依赖以便使用依赖注入

时间:2015-01-28 11:59:18

标签: java dependency-injection dagger-2

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

class Client {
  Handler h;

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

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

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

client = new Client(this);

所以现在我的问题是:设计有问题吗?可以将ClientHandler分开吗?或者我应该忍受这个并且不使用依赖注入everywhere

感谢您的建议

2 个答案:

答案 0 :(得分: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&lt; - client&lt; - handler

其中handler知道客户端和common 和客户只知道共同点。 (假设您将接口放在公共包中)

而不是 客户&lt; - &gt;处理

我故意使用sendSomeMessage强调它是你在包装器/界面上调用的另一种方法,但是你可以根据自己的喜好命名它们。

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

答案 1 :(得分:2)

我意识到我真正试图解决的问题并不是打破ClientHandler之间的依赖关系,而是使用依赖注入而不是new运算符。

我正在寻找的解决方案:将ClientFactory注入Handler的构造函数中,然后使用clientFactory.create(this)来创建Client对象。精彩的库AutoFactory允许您使用简单的@AutoFactory注释创建这样的工厂。创建的类的构造函数将使用@Inject自动注释。