Java - 2 пути "Имеет отношение"

Я только что начал проект, чтобы сделать моего работодателя управляющим программным обеспечением. У меня есть никчемный, но потенциально простой запрос, на который я не могу найти никакой информации.

Является ли разумным/хорошей практикой иметь 2-стороннюю связь между объектами. Так может, например, объект Client иметь "Site, а затем Site" имеет "Client", где объектом Client является Client, который имеет "Site?

public class Client {
    Site site;
}

public class Site {
    Client client;
}

Есть ли что-нибудь неприятное (не каламбур), или это нормально? В настоящее время я создаю макет UML для проекта, и это меня беспокоило.

Ответы

Ответ 1

Есть ли что-нибудь противное или это нормально?

Нет окончательного ответа на этот вопрос. Лучший ответ: это зависит от дизайна вашего приложения.

Когда использовать его

Если ваш объект Client должен перейти к объекту Site, а ваш объект Site должен перейти к объекту Client, тогда текущий пример в вашем коде будет в порядке. Тем не менее, возможно, вам понадобится какой-то способ связать эти элементы, возможно, с помощью дополнительного поля id в одном из классов или в обоих.

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

Если не использовать его

В принципе, для сериализации текста, поскольку он будет генерировать бесконечный цикл. Как уже упоминалось в ответе Raibaz, библиотека, подобная Джексону, попадет в бесконечный цикл, а сериализует класс Client или Site в строку JSON 1. Обратите внимание, что это также актуально при сериализации для других String данных, например, для передачи объектов через веб-службу JAX-WS в XML (подробнее: Что происходит с универсальным классом в jax-ws вебсервис?).

1 Это можно решить, используя аннотации (@Something), которые принадлежат определенной библиотеке, например. @JsonManagedReference и @JsonBackReference из библиотека Джексона, как отметил @SimonAndréForsberg, но недостатком этого решения является то, что ваши классы будут плотно связь с библиотекой.

Ответ 2

Обычно имеет взаимную связь между объектами.

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

Термин has-a часто используется для передачи права собственности на один объект другим. Когда это верно, отношения обычно односторонние.

Одно хорошее определение этих терминов приведено в "Руководстве пользователя унифицированного языка моделирования", автор: Booch, Rumbaugh и Jacobson:

Агрегация. Простая связь между двумя классами представляет собой структурную взаимосвязь между сверстниками, что означает, что оба класса концептуально находятся на одном уровне, не более важными, чем другие. Иногда вам нужно моделировать отношение "целое/часть", в котором один класс представляет собой нечто большее ( "целое" ), которое состоит из более мелких предметов ( "частей" ). Такое отношение называется агрегацией, которая представляет собой отношение "has-a", что означает, что объект целого имеет объекты этой части.

Ответ 3

Это обычное явление, но я бы рассмотрел, как слабо связанный вы хотите, чтобы дочерний объект был из его родителя. Если у вас есть ссылка на родителя из дочернего объекта, вы не сможете повторно использовать объект с другим родителем/без родителя.

Ответ 4

Это вполне нормально и довольно распространено иметь двунаправленную связь, подобную той, что приведена в вашем примере.

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

Ответ 5

Я попытался бы придерживаться односторонних отношений, когда это возможно. Двусторонние отношения объединяют два класса, а изменение одного из них заставляет другого изменить два. Спросите себя, действительно ли такое отношение является естественным...

Если вам нужно, просто убедитесь, что оба интерфейса или хотя бы один из них.