How exactly does dependency injection reduce coupling?

前端 未结 4 438
醉梦人生
醉梦人生 2020-12-14 21:16

I\'ve done plenty of reading on Dependency Injection, but I have no idea, how does it actually reduce coupling?

The analogy I have of DI is that all components are r

相关标签:
4条回答
  • 2020-12-14 21:35

    In DI one component calls another component only via a well-defined interface and all components "glue" together via configuration and not code.
    As a result we can swap implementations used by an application by re-configuration alone.
    As an example in containers you can visualize dependency-injection as a reversed look-up (if you have used JNDI). Instead of having resource/module names hard-coded, you declare what is needed for a class (acting as a bean).The container is responsible for providing everything at run time.
    This term was coined by Martin Fowler and you can check his article on the concept DI

    0 讨论(0)
  • 2020-12-14 21:43

    To go with your analogy of your components being in a treasure chest: A system (lets say a treasure polisher) without dependency injection has to have the ability to pick an item from the treasure chest itself. It has to have some knowledge the dependency's nature in order to pick the correct treasure to polish depending on the current context. Thus coupling.

    In a DI scenario, your treasure polisher does not need to know about the existence of the treasure chest at all. All it needs to know is that at some point (preferably at creation) the polisher will be provided (injected) with an object which implements ITreasure:

    interface ITreasure
    {
        void PolishMe();
    }
    

    Thus your implementation class is de-coupled from your treasure chest.

    0 讨论(0)
  • 2020-12-14 21:44

    The coupling is especially reduced if you use interfaces properly.

    If the client only knows about the interface, now the possibilities open up. You are freed to inject your own implementation or a proxied version; you can advise it with aspects without the client's knowledge; you can easily mock it during testing. The client need not know the concrete type as it would if you simply called "new".

    0 讨论(0)
  • 2020-12-14 21:54

    Dependency Injection (DI) doesn't reduce coupling, per se, because the component that relies on the dependency is still coupled to its dependency. What DI does accomplish, however, is to remove the responsibility of finding the dependency from the component itself, and placing that responsibility elsewhere.

    A component that relies on DI is completely passive when it comes to its dependencies. There is no code in the component that says "create a new instance of this dependency" or "go out and get me this dependency". The dependency is given to (injected into) the component, usually when the component itself is created by some other object.

    This reversal of responsibility to create (or ask for creation of) a dependency is called Inversion of Control (IoC).

    So, if the component doesn't know how to create or ask for a dependency, where does that responsibility lie? Usually in an object created specifically for dependency resolution, commonly called an IoC container. In your analogy, this is your "treasure chest". The IoC container contains the instructions that basically say "when somebody asks for this, give them one of these. An IoC container can typically inspect the component it's asked to create, figure out what its dependencies are, and create them too, walking down the "dependency chain" until all of the dependencies are resolved.

    The big shift in thinking, the injection, comes when deciding *who gets to ask the container for the component's dependency"? Without DI, it would be the component itself that would ask the container for its dependency. Using DI, however, the responsibility of asking the container to "resolve" a component's dependency falls to whatever creates or uses the component. When the component is created, whatever is creating it has the responsibility of providing all of the dependencies. The component doesn't know or care how they are created, just that they are.

    Now, if the dependency is defined as a concrete implementation, the component is still tightly coupled to that specific concrete implementation, even though it is being injected. DI itself does not reduce coupling in that sense. But if the dependency is defined as an interface, the component doesn't care or know what the concrete implementation is, nor how it's created. It's still coupled to the dependency, but it is a very loose coupling.

    In that sense, "Dependency Injection" and "Programming to Interfaces" combine to create very loosely coupled, highly flexible components.

    0 讨论(0)
提交回复
热议问题