Dependency Inversion Principle (SOLID) vs Encapsulation (Pillars of OOP)

后端 未结 7 704
被撕碎了的回忆
被撕碎了的回忆 2021-01-30 02:35

I was recently having a debate about the Dependency Inversion Principle, Inversion of Control and Dependency Injection. In relation to this topic we w

7条回答
  •  粉色の甜心
    2021-01-30 02:52

    Is IoC a direct implementation of the Dependency Inversion Principle?

    The two are related in a way that they talk about abstractions, but that's about it. Inversion of Control is:

    a design in which custom-written portions of a computer program receive the flow of control from a generic, reusable library (source)

    Inversion of control is allowing us to hook our custom code into the pipeline of a reusable library. In other words, Inversion control is about frameworks. A reusable library that does not apply Inversion of Control is merely a library. A framework is a reusable library that does apply Inversion of Control.

    Do note that we as developers can only apply Inversion of Control if we are writing a framework ourselves; you can't apply inversion of control as an application developer. We can (and should) however apply Dependency Inversion Principle and the Dependency Injection pattern.

    Does IoC always break encapsulation, and therefore OOP?

    Since IoC is just about hooking into the pipeline of a framework, there is nothing that's leaking here. So the real question is: does Dependency Injection break encapsulation.

    The answer to that question is: no, it does not. It doesn't break encapsulation because of two reasons:

    • Since the Dependency Inversion Principles states that we should program against an abstraction, a consumer will not be able to access the internals of the used implementation and that implementation will therefore not be breaking encapsulation to the client. The implementation might not even be known or accessible at compile time (because it lives in an unreferenced assembly) and the implementation can in that case not leak implementation details and break encapsulation.
    • Although the implementation accepts the dependencies it requires throughout its constructor, those dependencies will typically be stored in private fields and can't be accessed by anyone (even if a consumer depends directly on the concrete type) and it will therefore not break encapsulation.

    Should IoC be used sparingly, religiously or appropriately?

    Again, the question is "Should DIP and DI be used sparingly". In my opinion, the answer is: NO, you should actually use it throughout the application. Obviously, you should never apply things religiously. You should apply SOLID principles and the DIP is a crucial part of those principles. They will make your application more flexible and more maintainable and in most scenarios it is very appropriate to apply the SOLID principles.

    What is the difference between IoC and an IoC container?

    Dependency Injection is a pattern that can be applied either with or without a IoC container. An IoC container is merely a tool that can help building your object graph in a more convenient way, in case you have an application that applies the SOLID principles correctly. If you have an application that doesn't apply the SOLID principles, you will have a hard time using a IoC container. You will have a hard time applying Dependency Injection. Or let me put it more broadly, you will have a hard time maintaining your application anyway. But in no way an IoC container is a required tool. I'm developing and maintaining an IoC container for .NET, but I don't always use a container for all my applications. For the big BLOBAs (boring line of business applications) I often use a container, but for smaller apps (or windows services) I don't always use a container. But I do almost always use Dependency Injection as a pattern, because this is the most effective way to adhere to DIP.

    Note: Since an IoC container helps us in applying the Dependency Injection pattern, "IoC container" is a terrible name for such library.

    But despite of anything I said above, please note that:

    in the real world of the software developer, usefulness trumps theory [from Robert C. Martin's Agile Principle, Patterns and Practices]

    In other words, even if DI would break encapsulation, it wouldn't matter, because these techniques and patterns have proven to be very valuable, because it results in very flexible and maintainable systems. Practice trumps theory.

提交回复
热议问题