Вы можете использовать шаблон типа Observer, где Категория регистрирует интерес к определенным событиям в Продукте (возможно, событие ProductInactivation?), А затем обрабатывает логику соответствующим образом. Этот шаблон, основанный на событиях, очень распространен и значительно снижает связь. Категория в конечном итоге несет ответственность за свое собственное состояние и не полагается на то, что Продукт знает что-то о том, что в нем содержится, чтобы сохранить состояние категории в целости и сохранности. Продукт просто сообщает заинтересованным клиентам, когда с ним что-то произошло.
Другим вариантом является рефакторинг вашего класса Category так, чтобы он содержал или содержался в каком-либо объекте CategoryProductServices, который инкапсулирует методы, которые Продукт должен будет выполнить в своей содержащей Категории. В контексте, который создает Категории и Продукты, передайте экземпляр этого объекта CategoryProductServices в Продукт, а не в полную Категорию. Этот дизайн делает интерфейс общедоступным, но не позволяет вашему клиенту получить доступ к сервисам, поскольку они не могут получить экземпляр. Это также ослабляет тесную связь Продуктов с классом Категории, ограничивая его только теми услугами, о которых Продукты должны знать. Это оставляет Продукт ответственным за состояние, но по крайней мере ограничивает то, что ему нужно знать / делать.