Dependency Inversion Principle (DIP) — один из пяти принципов SOLID.
Это комбинация:
- DIP — зависимости направлены от верхнего уровня к нижнему, не наоборот
- Acyclic Dependencies Principle — нет циклических зависимостей (A → B → A)
- Law of Demeter — класс работает только со своими прямыми зависимостями, а не лезет через цепочку (
$this->service->getOther()->doStuff())
Основное правило простое: зависимости идут сверху вниз, никогда снизу вверх.
Представь свой плагин как слои:
SprmWpBlocks ← оркестратор (верх)
├── Services/Assets ← сервисы (середина)
├── Services/Acf
├── Services/I18n
└── blocks/ ← блоки (низ)
├── Statistics
├── Cta
└── AffiliateModels
Правила:
1. Верхний слой знает о нижних, не наоборот
// ✅ SprmWpBlocks знает о блоках и сервисах
Statistics::registerHooks();
Assets::registerHooks();
// ❌ Block знает о SprmWpBlocks — обратная зависимость
$css = SprmWpBlocks::styleFile(self::name()); // было раньше
2. Классы одного уровня не знают друг о друге
// ❌ Assets знает про Acf — оба сервисы
Acf::getAcfJsonPath();
// ❌ Statistics знает про Cta — оба блоки
Cta::renderBlock();
3. Ребёнок может знать о своём родителе (наследование)
// ✅ AffiliateModels наследует Block
class AffiliateModels extends Block {
parent::registerHooks(); // нормально
}
4. Все могут зависеть от абстракций (интерфейсы, трейты)
// ✅ кто угодно может реализовывать интерфейс
class Assets implements Hookable { }
class Statistics implements Hookable { }
Простой тест: если ты удалишь класс, кто сломается?
Удалил Statistics → сломается только SprmWpBlocks::init() ✅
Это значит что Statistics — независимый класс. Никто от него не зависит, кроме оркестратора который его подключает.
Если удалить Statistics:
SprmWpBlocks::init()— сломается (вызываетStatistics::registerHooks()) ✅Assets,Acf,Cta,AffiliateModels— работают как раньше ✅
Это и есть признак правильной архитектуры: каждый класс можно убрать/добавить, поправив только одну строку в оркестраторе.
2. Удалил SprmWpBlocks → сломается AffiliateModels ❌
Так было раньше, когда блок обращался к SprmWpBlocks::styleFile().