Question

How do I best decouple two classes but still have them depend on each other?

I have constructor arguments with type hinting:

public function __construct(\namespace\Interface1 $class1,
    \namespace\Interface2 $class2,
    \other\namespace\Abstract1 $class3){

But is this as tightly coupled as, say:

new \namespace\Class1();

Any other methods welcome.

Was it helpful?

Solution

Using an interface means you are decoupled from the implementations.

You cannot use another component (i.e. a dependency) without being coupled to at least something. The question is how to minimize this coupling:

  • instantiating the dependency yourself means being coupled to the class, the constructor of that class and all the sub-dependencies of your dependency. That is very bad.
  • requiring/type-hinting (in a constructor parameter) an object of a specific class means you are strongly coupled to the class. If you ever want to change the class, you are screwed. This is bad.
  • requiring/type-hinting an object implementing an interface means you only couple yourself to the interface. That means you can have any implementation of that interface. This is good, you are not very coupled to your dependencies, you just need an object that can do X (X being the contract defined by the interface).

In the end, that's about choosing the solution that involves the less coupling.

An alternative to this would be to use events: your class could raise events, and have dependencies listen to those events. That way, your class is only coupled to an interface of an EventManager.

But the event solution doesn't really fit every use case: you have no guarantee that anyone actually registered to the event, and actually did something on that event. And you can't get the result back like you could if you just called a method.

Conclusion: using an interface like you do is good, there is no problem here. :)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top