TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.75K subscribers
Post #577 1.08K
День четыреста семьдесят четвёртый. #DesignPatterns
Принципы SOLID.
5. Принцип инверсии зависимостей (DIP)
«Модули верхнего уровня не должны зависеть от модулей нижнего уровня. И те и другие должны зависеть от абстракций. Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций» (Мартин Р. Принципы, паттерны и практики гибкой разработки. — 2006).

Принцип инверсии зависимостей лежит в основе популярных техник внедрения зависимостей (Dependency Injection). В основе принципа инверсии зависимостей лежит идея использования интерфейсов. Одна группа классов реализует некоторый набор интерфейсов, а другая — принимает эти интерфейсы в качестве аргументов конструктора.
interface IReader {
string Read();
}
class Report {
public Report(IReader reader) {…}
}
class FileReader : IReader {…}

Использование интерфейсов приводит к слабосвязанному (loosely coupled) дизайну, поскольку класс Report знает лишь об интерфейсе IReader и не знает о конкретной реализации этого интерфейса. А следование принципу LSP позволит заменить одну реализацию другой и получить гибкое решение, соответствующее принципу OCP.

Однако не стоит забывать, что наличие интерфейсов образует дополнительный уровень абстракции, что затрудняет понимание системы. Не для всех классов нужно выделять интерфейсы, и не все зависимости следует требовать извне в виде интерфейсов.

Слои
Любое современное приложение разбито на слои, каждый из которых отвечает за определенный аспект поведения: доступа к данным, бизнес-логики, UI и т.п. Каждый слой отвечает за определенную область и использует сервисы нижележащих уровней для решения своих задач. Принцип SRP говорит, что каждый класс, модуль или слой должен решать лишь одну задачу. Это значит, что код доступа к данным не должен содержать бизнес-логики, а бизнес-логика не должна знать о UI. Слои нижнего уровня не знают и не должны знать о слоях верхнего уровня. Это позволяет использовать низкоуровневые слои повторно, упрощает понимание и развитие каждого из них, а также ограничивает распространение изменений.

Для чего нужен DIP
DIP предназначен для устранения прямых связей между классами или модулями с зависимостями более высокого уровня. Название отражает нетипичность направления зависимостей: классы нижнего уровня определяют некоторый контракт, которому должны следовать классы верхнего уровня. Классы верхнего уровня вынуждены выступать в роли адаптеров и подстраиваться под протокол, определенный на уровне ниже.

Примеры нарушения DIP
1. Низкоуровневые классы напрямую общаются с высокоуровневыми классами: модели в MVC знают о UI или код доступа к данным знает о бизнес-логике.
2. Классы принимают слишком низкоуровневые интерфейсы, такие как IFileStream, что может привести к подрыву инкапсуляции и излишнему увеличению сложности.

Принцип DIP не сводится лишь к выделению интерфейсов и передаче их через конструктор. DIP объясняет, для чего нужно это делать. Классы имеют право контролировать свои детали реализации, но некоторые аспекты находятся за пределами их компетенции. Чтобы не завязываться на классы верхнего уровня, класс может объявить некоторый интерфейс и потребовать его экземпляр через аргументы конструктора. Таким образом мы можем инвертировать зависимости и позволить классам нижних уровней взаимодействовать с другими частями системы, ничего конкретного о них не зная.

Источник: Тепляков С. "Паттерны проектирования на платформе .NET." — СПб.: Питер, 2015. Глава 21.
More from @netdeveloperdiary
  1. Sep 30, 2026Post #3356
  2. Sep 29, 2026Фото 3 (с) Анатолий Кулаков
  3. Sep 29, 2026День 2799. Конференция DotNext 2026. Часть 1 25 и 26 сентября в Москве прошла очередная ко…
  4. Sep 28, 2026День 2798. #Оффтоп Утиная Типизация в C# с Помощью Перехватчиков. Часть 2 Некоторое время…
  5. Sep 27, 2026День 2797. #ЗаметкиНаПолях #AI Рабочий процесс с Copilot для .NET. Окончание Начало Продол…
  6. Sep 26, 2026День 2796. #ЗаметкиНаПолях #AI Рабочий процесс с Copilot для .NET. Продолжение Начало Три…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →