Это нормально, чтобы мой графический интерфейс зависел от конкретного класса контроллера
напрямую? Почему / почему нет?
Нет: потому что слабая связь имеет основополагающее значение для хорошего дизайна. Зависит от абстракций. Зависимость от реализаций делает невозможной замену одной реализации на другую без перекомпиляции зависимой, по крайней мере. Плотное соединение любых двух классов препятствует будущей гибкости.
Да: это призывный суд. Если слабая связь определенно не имеет никакой будущей выгоды и является слишком дорогой, чтобы оправдать, уйдите.
Но на самом деле старайтесь не делать этого. Наличие графического интерфейса пользователя зависит от контроллера - это правильное проектное решение. Но всегда зависит от абстракций, а не от реализаций. Давай ... ты знал это. Я имею в виду, хорошо, если никто никогда не хочет отключить контроллер, то вы ничего не получили с помощью интерфейса. За исключением душевного спокойствия, зная, что вы написали более аккуратный, менее связанный код. И, возможно, легче проверить.
Что касается выбора того, как происходит обмен данными между графическим интерфейсом и контроллером, то это проблема. Вы можете использовать события, но их подключение - это перетаскивание, и они не будут пересекать границы приложения. Но, используя события, вы можете почувствовать, что у вас самая слабая связь. Графический интерфейс и контроллер никогда не должны обращаться (абстракции) друг к другу, кроме как для первоначального подключения событий. Это может быть приятно. Или вы можете использовать вызовы методов для интерфейсов, что может показаться немного более жесткой связью, но на самом деле это вряд ли отличается. В любом случае, X должен знать кое-что о Y, чтобы они могли общаться.
Круговые зависимости между графическим интерфейсом и контроллером в порядке (для абстракций!). Есть много вариантов паттерна MVC. Каждый раз, когда я использую это, я формирую это к своим потребностям / настроению. Тем не менее, я стараюсь избегать циклических зависимостей. Я предпочитаю ограничивать зависимости в одном направлении. Или вообще ничего!
Например, в моем текущем проекте контроллеры знают о представлениях, но представления не имеют абсолютно никакого представления о выходе контроллеров. Контроллеры присваивают событиям представления и передают им данные через один объект состояния, к которому привязывается представление. Государственный класс - единственное, от чего зависит представление. И единственное, что контроллер знает о представлении, это его интерфейс и тип его объекта состояния. И эти вещи определены во внешнем модуле, так что модуль представления может быть полностью удален, а контроллер все равно будет компилироваться, и наоборот. Это очень слабая связь. Почти нет (обе стороны зависят от третьего модуля).
Некоторые люди делают это наоборот.
Причины, чтобы избежать конкретных зависимостей
- Сложно поменять один объект на другой - зависимому, вероятно, потребуется модификация или, по крайней мере, перекомпиляция.
- сложнее в обслуживании - не может изменять компоненты независимо друг от друга
- сложнее тестировать изолированно - нужно модифицировать и перекомпилировать зависимые для свопинга в фиктивной реализации зависимости