I have two interfaces: Camera and Computer. So far, each interfaces have multiple implementations in my codebase and they are loosely coupled (no implementations of Camera depends on any implementations of Computer and vice versa).

Now I am interested to create a new class called DigitalCamera. DigitalCamera optionally requires input from a Computer to perform its functions. What it needs is a dictionary of integers from whichever Computer I am currently using in my codebase.

I am aware that this usage will break the principle of loosely coupled so I want to explore the best options to minimize pain down the road.

How should I write my DigitalCamera class to support this functionality?

I am using Java if that matters.

=== EDIT ===

To address some of your questions:

  1. It is only one implementation of Camera that depends on Computer. Not all cameras depend on computers
  2. The data can be passed in multiple ways: (i) calling DigitalCamera.setData(...), (ii) calling the API method with additional arguments, (iii) passing a CompletableFuture that returns a Map, etc. I haven't decided what is the best way to do this.
  • But it's the implementation that depends on Computer, not the interface. So not sure I understand your problem. Also, how will Camera receive that dictionary? Will it ask for it? Or will it be notified by the Computer? Aug 13, 2021 at 19:39
  • 2
    I am not sure I understand, but I think there is some confusion. There is absolutely nothing wrong with coupling to an interface. The problem occurs when you couple to a specific implementation of that interface. But if your code depends on a specific interface, that is fine-- in fact, you wouldn't be able to write very interesting software without it.
    – John Wu
    Aug 13, 2021 at 22:22
  • That's a bit of an over-simplification. It's not that coupling to one thing is fine and another is not. Coupling is always bad, but you have to couple to some things to make usable software. You should try to couple to stable things. The more stable the things you couple to, the better. If you couple to an unstable thing, you will be affected when the unstable thing changes. Then as a general principle, interfaces are more stable than implementations, but that's not always the case with all interfaces and all implementations.
    – kqr
    Aug 14, 2021 at 4:47
  • @kqr Suggesting "coupling is always bad" implies "decoupling is always good", however that line of thought is food for unnecessarily decoupling from things which are highly unlikely to ever change, causing unnecessary complexity (violating KISS and YAGNI principles) whose negative effects can include code which is harder to understand, and behaviour which is harder to observe or reason about. In reality, coupling is only bad at the point in time when it becomes an impediment (e.g. needing to change the code or write a test), otherwise it can also have benefits in reduced complexity. Aug 14, 2021 at 9:34
  • Pass the computer in through the constructor (as an IComputer interface), store it as a private member field, and then implement your API method to ask the computer for the data internally (unless the field is null, since it's optional). This assumes that the IComputer abstraction supports this capability. Aug 14, 2021 at 11:19


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy