Наличие двунаправленного отношения - это, конечно, круговая зависимость, но очень особый случай, который может быть принят, если рассматривать его соответствующим образом.Все другие циклические зависимости должны быть опущены, если это возможно (что не всегда так, тогда им нужно еще больше уважения, особенно при обслуживании такой системы).
Чтобы разбить циклические зависимости, доступно несколько методов по умолчанию.В основном это работает, чтобы вытащить интерфейсную часть и сделать зависимости от реализаций только для интерфейсов вместо классов.Это также дает ряд других преимуществ, таких как улучшенное повторное использование, расширяемость или тестируемость.
В данном конкретном случае я буду ссылаться на паттерн наблюдателя, предложенный как часть классических паттернов GoF.Там у вас есть (абстрактный) класс наблюдателя, который будет вашим модулем, который реализует метод, который вызывается для уведомления об обновлении.И есть предметный класс, который будет вашим классом UnitManager.Класс UnitManager знает только, то есть зависит от абстрактного класса или интерфейса наблюдателя, а не от конкретных.И каждый класс модулей, который может инициировать обновление всех других экземпляров модулей, будет зависеть от UnitManger (или когда он является следствием абстрактного суперкласса или его интерфейса).
Если вы захотите разобраться с близостью, это сильно зависит от того, как выглядит оставшийся логис и как он реализован.Основным решением будет регистрация и отмена регистрации единиц в соответствии с их расстоянием.Другой вариант заключается в том, что UnitManager вызывает только тех зарегистрированных наблюдателей, которые находятся достаточно близко.