Принцип инверсии зависимостей в объектно-ориентированном проектировании
Dependency inversion principle
Принцип инверсии зависимостей в объектно-ориентированном программировании: снижение связанности модулей, абстракции высокого и низкого уровня. ООП, дизайн.
В объектно-ориентированном проектировании принцип инверсии зависимостей – это конкретная методология для создания слабосвязанных программных модулей. При следовании этому принципу, традиционные зависимости, устанавливаемые от модулей высокого уровня, определяющих политику, к модулям низкого уровня, от которых зависят другие модули, меняются местами, что делает модули высокого уровня независимыми от деталей реализации модулей низкого уровня. Принцип утверждает:
In object oriented design, the dependency inversion principle is a specific methodology for loosely coupled software modules. When following this principle, the conventional dependency relationships established from high level, policy setting modules to low level, dependency modules are reversed, thus rendering high level modules independent of the low level module implementation details. The principle states:
Предписывая, чтобы объекты как высокого, так и низкого уровня должны зависеть от одной и той же абстракции, этот принцип проектирования меняет представление о объектно-ориентированном программировании, которое есть у некоторых разработчиков. Идея, лежащая в основе пунктов А и В этого принципа, заключается в том, что при проектировании взаимодействия между модулем высокого и низкого уровня, это взаимодействие следует рассматривать как абстрактное. Это оказывает влияние не только на проектирование модуля высокого уровня, но и на модуль низкого уровня: последний должен быть спроектирован с учетом этого взаимодействия, и может потребоваться изменить его интерфейс. Во многих случаях, рассмотрение самого взаимодействия как абстрактного понятия позволяет уменьшить связанность компонентов без использования дополнительных шаблонов кодирования, обеспечивая более простую и менее зависимую от реализации схему взаимодействия. Когда обнаруженная абстрактная схема взаимодействия между двумя модулями является универсальной и обобщение оправдано, этот принцип проектирования также приводит к следующему шаблону кодирования инверсии зависимостей.
By dictating that both high level and low level objects must depend on the same abstraction, this design principle inverts the way some people may think about object oriented programming. The idea behind points A and B of this principle is that when designing the interaction between a high level module and a low level one, the interaction should be thought of as an abstract interaction between them. This not only has implications on the design of the high level module, but also on the low level one: the low level one should be designed with the interaction in mind and it may be necessary to change its usage interface. In many cases, thinking about the interaction in itself as an abstract concept allows the coupling of the components to be reduced without introducing additional coding patterns, allowing only a lighter and less implementation dependent interaction schema. When the discovered abstract interaction schema(s) between two modules is/are generic and the generalization makes sense, this design principle also leads to the following dependency inversion coding pattern.
Традиционный слойный рисунок
В традиционной архитектуре приложений компоненты нижнего уровня (например, уровень утилит) разрабатываются для использования компонентами верхнего уровня (например, уровень политик), что позволяет создавать все более сложные системы. В такой структуре компоненты верхнего уровня напрямую зависят от компонентов нижнего уровня для выполнения определенных задач. Эта зависимость от компонентов нижнего уровня ограничивает возможности повторного использования компонентов верхнего уровня. Для решения этой проблемы используются внедрение зависимостей, которое облегчает предоставление выбранной реализации компонента нижнего уровня компоненту верхнего уровня во время выполнения.
In conventional application architecture, lower level components (e. g., Utility Layer) are designed to be consumed by higher level components (e. g., Policy Layer) which enable increasingly complex systems to be built. In this composition, higher level components depend directly upon lower level components to achieve some task. This dependency upon lower level components limits the reuse opportunities of the higher level components. or Dependency injection are employed to facilitate the run time provisioning of the chosen low level component implementation to the high level component.
История
Принцип инверсии зависимостей был сформулирован Робертом К. Мартином и описан в ряде публикаций, включая статью «Объектно-ориентированные метрики качества проектирования: анализ зависимостей», статью «Принцип инверсии зависимостей», опубликованную в журнале C++ Report в июне 1996 года, а также книги «Гибкая разработка программного обеспечения: принципы, шаблоны и практики» и «Гибкие принципы, шаблоны и практики в C#».
The dependency inversion principle was postulated by Robert C. Martin and described in several publications including the paper Object Oriented Design Quality Metrics: an analysis of dependencies, an article appearing in the C++ Report in June 1996 entitled The Dependency Inversion Principle, and the books Agile Software Development, Principles, Patterns, and Practices, and Agile Principles, Patterns, and Practices in C#.