Как смешно, я вижу один ответ в каждом направлении!
В любом случае, что я рекомендую вам сделать, следуя опции № 1 (добавить переменную-член в класс X, указывая на экземпляр Y) с помощьюНебольшое исправление: используйте интерфейс вместо .
Таким образом, каждый модуль будет иметь интерфейс.Этот интерфейс будет иметь методы, которые могут понадобиться людям извне для выполнения своей работы.Все остальное скрыто от них.
Когда создается модуль A, если ему нужно использовать функции модуля B, вы будете делать что-то вроде setModuleBHandler(moduleB)
.
Таким образом, вы можетеизмените модули, которые делают то, что вам нужно, без того, чтобы вызывающий абонент заметил это (поскольку интерфейс по-прежнему соблюдается).
Это позволит вам следовать другим рекомендациям, таким как TDD.
Пример:
Предположим, что модуль Broker нуждается в регистрации (и у вас есть модуль, предназначенный для регистрации).Вместо объявления public void setLogger(Logger logger)
предпочтительнее объявить его следующим образом: public void setLogger(LoggerInterface logger)
.
Это почти то же самое.То, что работало раньше, все равно будет работать.Разница в том, что теперь вы можете использовать совершенно другую реализацию Logger, не беспокоясь о влиянии на множество модулей, которые могут их использовать.
Например, у вас может быть класс TextLogger, реализующий интерфейс, и другойDBLogger реализует тот же интерфейс.Вы можете поменять их местами, не ожидая каких-либо проблем.
Примечание: использование абстрактного класса даст вам почти такие же результаты.
Я знаю, что этот небольшой пример не показывает должным образом все преимуществаиз этого выбора, и многие люди смогут найти недостатки в этом, но я твердо верю, что это лучший выбор для большинства случаев (конечно, каждый случай является случаем).