Внедрение зависимости для разрешения круговых зависимостей

Пример:

class MyClass
{
    Composition m_Composition;

    void MyClass()
    {
        m_Composition = new Composition( this );
    }
}

Я интересуюсь использованием depenency-инжекции здесь. Таким образом, я должен буду осуществить рефакторинг конструктора к чему-то как:

void MyClass( Composition composition )
{
    m_Composition = composition;
}

Однако я получаю проблему теперь, начиная с Composition- объект полагается на объект типа MyClass который просто создается.

Контейнер зависимости может разрешить это? Это, как предполагается, делает так?
Или это - просто плохой дизайн с начала на?

10
задан Mogsdad 26 September 2015 в 13:03
поделиться

1 ответ

Нет , контейнер DI не решит циклическую зависимость - фактически, он будет протестовать против этого, выбрасывая исключения, когда вы пытаетесь разрешить зависимости.

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

Как показывает практика, круговая зависимость - это запах дизайна . Если можете, рассмотрите альтернативный дизайн, в котором вы избавитесь от циклической зависимости - это также даст вам меньшее связывание . Некоторые возможные альтернативы перепроектирования:

  • Используйте события для передачи сигналов от одного класса к другому. Часто круговая зависимость уже в основном идет в одном направлении, и когда это так, моделирование части этого сигнального API, поскольку события могут разрезать круг.
  • Если вышесказанное верно, но вы чувствуете, что события кажутся неправильными, вы можете рассмотреть возможность применения шаблона Наблюдатель .
  • Если связь действительно должна идти в обоих направлениях, вы можете использовать Посредник , через который компоненты могут обмениваться данными.

Тем не менее, я намеренно выбрал слово запах вместо антипаттерн , поскольку есть угловые случаи (особенно когда вы имеете дело с внешне определенными API), когда невозможно избежать циклических зависимостей.

В таких случаях вам нужно решить, где немного ослабить создание зависимости. Как только вы это узнаете, внедрение абстрактной фабрики может быть полезным, чтобы отложить одно из творений до тех пор, пока не будут созданы другие части круга.

Этот другой ответ - лучший доступный пример, о котором я сейчас знаю, но если я буду таким смелым, моя будущая книга также будет содержать раздел, посвященный этой самой проблеме.

12
ответ дан 4 December 2019 в 00:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: