0

I have read up on dependency injection and interfaces, but I am still confused about the best way to decouple packages in my situation. Say I have a UIClass in UIPackage:

package UIPackage;

import NetworkPackage.NetworkClass

class UIClass() {
    public static void displayMessage(String message) {
        // show the message on screen
    }

    private static void messageEntered(String message) {
        NetworkClass.sendMessage(message);
    }
}

and a NetworkClass in NetworkPackage:

package NetworkPackage;

import UIPackage.UIClass;

class NetworkClass() {
    public static void sendMessage(String message) {
        // send the message to the network
    }

    private static void messageReceived(String message) {
        UIClass.displayMessage(message)
    }
}

These packages depend on each other, but I would like to have the network package work independently of the UI package to remove the dependency cycle. The only way I have found to do that so far is to create an interface for the UIClass to implement (UIInterface), and then an instance of UIInterface is passed to the NetworkController in the constructor or something. This seems like it just makes things more complicated though as that interface would need to be in its own package which is then included in both of the original packages.

Should I create a third package for interfaces of this type? Should I just leave the circular dependency and not worry about it?

Clarification 1 This is not the code I am actually using, I just named the packages that way so that the example would be clearer. The app uses multiple threads, which is why NetworkClass needs a references to UIClass, because it is constantly waiting for a new message while the UI may be doing other things on a different thread. When a message is received, it needs to be able to update the UI and display the message. These packages have many other classes that do other things, but for the sake of example these classes are all that is exposed.

Marcos Vasconcelos
  • 18,136
  • 30
  • 106
  • 167
  • You cannot leave the circular dependency as you will not be able to build your code. It looks like you need to redesign your architecture. if A depends on B and B depends on A. There should be a module C that both A and B depend on. So pull out the pieces from A that B depends on and the parts from B that A depends on and put them in C. Hope that helps – nLee Apr 05 '18 at 17:34
  • also, package names should be lower cased :) – nLee Apr 05 '18 at 17:37
  • Ideal answer is yes, you should create an Interface to remove cyclic dependency. You think its complicated but its actually not, its gives you extensibility. – Afgan Apr 05 '18 at 17:40

2 Answers2

0

Of course you should care, just as you should pay attention to Java coding conventions.

I think embedding "Package" in package names and "Class" in class names is brain dead. Hungarian notation fell out of favor decades ago. Take those out.

This is a bad design.

I don't know what your Network class is for. I see no reason for Network to know or care about the Client that calls it. If the Client has a reference to a Network injected into its constructor, it should be able to use it to send the call, get the response back, and display it. No good reason for giving a Client reference to Network.

No more circular dependency.

I'd expect something more like a four tier architecture:

client -> controller -> services -> persistence

This is a request/response arrangement typical of web applications. The UI sends a request to a controller/listener, which orchestrates services and persistence to fulfill the use case and send the response back to the UI.

The picture changes if you go with an asynchronous, event based architecture.

duffymo
  • 305,152
  • 44
  • 369
  • 561
0

A circular dependency means generally a strong coupling between two components/things.
Is it ever a problem ? It is very often but not always.

3 examples where it may cause an issue :

1) if the dependencies try to create themselves by passing the other as parameter. Which is obviously not possible. Using an approach that sets one of the dependency or both after instances construction is a way to solve it.

2) if the code of the dependencies changes frequently enough as a change on one class could have side effect or break the code of the other.
It is like if these classes were a single class while this is not the case.

3) if you want reuse one of the dependencies alone in other contexts or applications.
You could not as both cannot live without the other one.
So it can defeat reduce or prevent dependency reusability.

davidxxx
  • 125,838
  • 23
  • 214
  • 215