-2

I've read that you should pass in an interface instead of a concrete implementation so that the consumer doesn't need to know anything about implementation details.

I don't understand how injecting a concrete class exposes implementation details?

class ServiceA() {
   private something

   public method1(){
     res = doSomething(this.something)
     res = doSomethingElse()
     return res; 
  }
}

interface Service {
   method1(): something
}

How does injecting ServiceA expose anything about the implementation? The consumer would still only have access to method1 right?

4
  • Think beyond a single class/object; you can implement things in terms of a number of collaborating objects, with the clients (at use time, although perhaps not at construction time) only being aware of a single class and satellite interfaces and data structures (like parameter and return types). So, a concrete class that you inject would be an implementation detail of this collaborating group; in your example the ServiceA would be an implementation detail, and client code wouldn't know about that type - which allows you to plug in ServiceB if you want. Commented Jan 24, 2023 at 5:54
  • So, for clarification, in the scenario above, the consumer (client) of interest is not the class where you inject the Service, but the code that calls that (host) class. Commented Jan 24, 2023 at 5:58
  • 3
    The answer is in whatever came before and after that sentence. Unless you have read that from a fortune cookie, the context matters.
    – Laiv
    Commented Jan 24, 2023 at 9:29
  • Note, my close vote was "needs details or clarification" (read your own code again, then think why I voted that way). Others have voted this as being a dupe, but that other question was IMHO equally unclear as this one, so I cannot really say it if it is really a dupe or not.
    – Doc Brown
    Commented Jan 24, 2023 at 17:53

2 Answers 2

3

The prohibition is against directly depending on a concrete type not against injecting one. It's mentioned in the Dependency Inversion Principle.

It says rather than doing this:

enter image description here

You should do this:

enter image description here

You can do that while injecting Mechanism into Policy just fine. The point is, statically, Policy should have no idea what is going to be injected. All it knows is that it'll be some Mechanism like thingy. Knowing that tells Policy how to talk to it. But that doesn't tell Policy what the Mechanism will do about what it is told because Policy doesn't, statically, know which Mechanism this even is. That hides the implementation details.

All of that is defeated if Policy constructs Mechanism itself and so knows exactly which Mechanism it's depending on. That would be "directly depending".

Something else constructing Mechanism and injecting it into Policy is fine so long as Policy knows no more about it than what the interface tells it.

This may sound like you need the keyword interface but really you just need some kind of abstraction. Which is nice because some languages don't even have that keyword.

-2

A class may implement several interfaces. So access to one interface only allows access to that one interface, access to the class would allow access to all interfaces.

Whether that is “access to the implementation” is dubious, but it is definitely access to more functionality than needed. But the question is strange: The consumer would define the type of object it consumes. If it is declared to consume an interface, any class would actually be reduced to that interface in the call. The consumer would never see the class. Now if the consumer declared that it wants some class, that’s just a daft thing to do.

Not the answer you're looking for? Browse other questions tagged or ask your own question.