Рассмотрим этот пример:
У меня есть сайт. Это позволяет пользователям создавать сообщения (может быть что угодно) и добавлять теги, которые описывают сообщение. В коде у меня есть два класса, которые представляют пост и теги. Давайте назовем эти классы Post
и Tag
.
Post
заботится о создании сообщений, удалении сообщений, обновлении сообщений и т. д.
Tag
заботится о создании тегов, удалении тегов, обновлении тегов и т. д.
Существует одна операция, которая отсутствует. Связывание тегов с постами. Я борюсь с тем, кто должен сделать эту операцию. Это может одинаково хорошо вписаться в любой класс.
С одной стороны, у Post
класса может быть функция, которая принимает Tag
параметр в качестве параметра, а затем сохраняет его в списке тегов. С другой стороны, Tag
класс может иметь функцию, которая принимает Post
параметр в качестве параметра и связывает Tag
его с Post
.
Выше приведен только пример моей проблемы. Я на самом деле сталкиваюсь с этим с несколькими классами, которые все похожи. Это может одинаково хорошо вписаться в обоих. Если не считать фактического включения функциональности в оба класса, какие соглашения или стили дизайна существуют, чтобы помочь мне решить эту проблему. Я предполагаю, что должно быть что-то не то, чтобы просто выбрать один?
Может быть, это правильное решение для обоих классов?
Нет, не в обоих! Это должно быть в одном месте.
То, что я нахожу неловким в вашем вопросе, это то, что вы говорите: «
Post
заботится о создании постов, удалении постов, обновлении постов» и то же дляTag
. Ну, это не правильно.Post
можно только позаботиться об обновлении, то же самое дляTag
. Создание и удаление - это работа кого-то другого, внеPost
иTag
(давайте просто назовем этоStore
).Хорошая ответственность за
Post
это "знает его автора, содержание и дату последнего обновления". Хорошая ответственность заTag
это «знает свое имя и цель (читай: описание)». Хорошая ответственность заStore
это "знает все сообщения и все теги и может добавлять, удалять и искать их".Если вы посмотрите на этих трех участников, кто наиболее естественно должен знать об отношениях Post-Tag?
(для меня это сообщение, кажется естественным, что оно «знает свои теги»; обратный поиск (все сообщения для тега), похоже, работа магазина, хотя я могу ошибаться)
источник
ConditionalWeakTable
(если предположить, что кому-то повезло, что у него есть структура, в которой он существует)?Theres важная деталь отсутствует в уравнении. Почему тег содержит почту и наоборот? Ответ на этот вопрос определяет решение для каждого данного набора.
В общем, я могу думать о ситуации, которая похожа. Коробка и содержимое. У блока есть содержимое, поэтому отношение has-a уместно. Может ли содержимое иметь коробку? Конечно, коробка с коробкой. Коробка с содержимым. Но IS-A - это не хороший дизайн для всех коробок. В таком случае я бы рассмотрел шаблон декоратора. Таким образом, коробка по мере необходимости украшается содержимым во время выполнения.
Теги тоже могут иметь сообщения, но для меня это не статичные отношения. Скорее это может быть отчет обо всех сообщениях, имеющих указанный тег. В этом случае это новая сущность, а не has-a.
источник
Хотя в теории подобные вещи могут идти в любом направлении, на практике, когда вы переходите к реализации, один из способов почти всегда подходит лучше, чем другой. Я догадываюсь, что это будет лучше вписываться в
Post
класс, потому что связь будет создаваться во время создания или редактирования поста, когда другие вещи в посте меняются одновременно.Кроме того, если вы связываете несколько тегов и хотите сделать это в одном обновлении базы данных, вам нужно создать какой-то список всех тегов, связанных с одним и тем же сообщением, перед выполнением обновления. Этот список намного лучше вписывается в
Post
класс.источник
Лично я бы не добавил эту функциональность ни к одному из них.
Для меня оба
Post
иTag
являются объектами данных, поэтому не должны обрабатывать функциональность базы данных. Они должны просто существовать. Они предназначены для хранения данных и используются другими частями вашего приложения.Вместо этого у меня был бы другой класс, отвечающий за вашу бизнес-логику и данные, относящиеся к вашей веб-странице. Если ваша страница отображает сообщение и позволяет пользователям добавлять теги, то у класса будет
Post
объект и функции, которые можно добавитьTags
к немуPost
. Если ваша страница отображает теги и позволяет пользователям добавлять сообщения в эти теги, она будет содержатьTag
объект и иметь возможность добавлятьPosts
к немуTag
.Это только я, хотя. Если вы чувствуете, что должны обрабатывать функциональность базы данных в ваших объектах данных, я бы порекомендовал ответ pdr
источник
Когда я читал этот вопрос, первое, что пришло на ум, было отношение базы данных « Многие ко многим» . В сообщениях может быть много тегов ... В тегах может быть много сообщений ... Мне кажется, что оба класса нуждаются в некоторой степени для управления этими отношениями.
С точки зрения публикации ...
Если ваше редактирование или создание публикации вторичным действием становится управление отношениями тегов .
ИМО, создание совершенно нового TAG здесь не относится.
С точки зрения тегов ...
Вы можете создать тег, не назначая его для публикации. Единственное, что я вижу, это взаимодействие с постом, это функция удаления тега. Однако эта функция должна быть независимой автономной функцией.
Это будет работать только при наличии таблицы связи базы данных, которая разрешает отношение «многие ко многим»
источник