Два объекта с зависимостями друг для друга. Это плохо? - PullRequest
7 голосов
/ 11 апреля 2010

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

В настоящее время я создаю небольшой чат-сервер с использованием сокетов с несколькими Клиентами. Прямо сейчас у меня есть три класса:

  1. Персональный класс , который содержит такую ​​информацию, как ник, возраст и объект комнаты.
  2. Класс комнаты , в котором хранится такая информация, как название комнаты, тема и список людей, находящихся в настоящее время в этой комнате.
  3. Отель-класс , в котором есть список лиц и список номеров на сервере.

Я сделал диаграмму, чтобы проиллюстрировать это:

У меня есть список людей на сервере в гостиничном классе, потому что было бы неплохо отслеживать, сколько сейчас онлайн (без необходимости перебирать все комнаты). Люди живут в гостиничном классе, потому что я хотел бы иметь возможность искать конкретного человека, не обыскивая комнаты.

Это плохой дизайн? Есть ли другой способ добиться этого?

Спасибо.

Ответы [ 4 ]

9 голосов
/ 11 апреля 2010

Мне это не нравится. В отеле есть номера, а в номерах - люди. У людей нет комнат, они принадлежат им.

Вам не обязательно повторяться, чтобы получить количество гостей. Вы можете просто сохранить счетчик ($ Hotel-> total_gtests) и изменять его по мере его изменения.

4 голосов
/ 11 апреля 2010

Проблема взаимной зависимости между классами, строго говоря, может быть решена с помощью интерфейсов (абстрактных классов, если ваш язык, например, C ++ или Python) IRoom и IPerson; в псевдокоде

interface IPerson
    IRoom getRoom()
    // etc

interface IRoom
    iter<IPerson> iterPerson()
    // etc

это делает только интерфейсы взаимозависимыми друг от друга - фактические реализации интерфейсов должны зависеть только от интерфейсов.

Это также дает вам много возможностей с точки зрения реализации, если вы хотите избежать циклических ссылочных циклов (что может мешать, например, в CPython, замедляя сборку мусора) - вы можете использовать слабые ссылки базовая реляционная база данных с типичной таблицей отношений «один ко многим» и т. д., и т. д. И для первого простого прототипа вы можете использовать то, что является самым простым в выбранном вами языке (возможно, простые и, увы, обязательно круговые, ссылки [[указатели, в C ++]] с Person, относящимся к Room и Room к list<Person>).

1 голос
/ 11 апреля 2010

В большой системе это было бы плохо, но, насколько я понимаю, из ваших приложений эти три класса используются только вместе, это не большая проблема. Обязательно назовите переменные-члены человека так, чтобы это указывало на то, что они содержат ссылку на комнату, а не на экземпляр.

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

0 голосов
/ 11 апреля 2010

Взаимная зависимость сама по себе неплоха. Иногда использование данных требует этого.

Я думаю об этом по-другому. Будет проще поддерживать код, который имеет меньше отношений в целом - взаимозависимость или нет. Просто держите это как можно проще. Единственная дополнительная хитрость в вашей ситуации - иногда возникает проблема проверки и яйца, во время создания и удаления последовательностей. У вас есть больше ссылок на бухгалтерию.

Если вы спрашиваете, нужен ли вам список людей в отеле в этом случае, я думаю, что есть два ответа. Я бы начал с того, что ваши объекты (в памяти) обеспечивают эти отношения, но вам НЕ нужна дополнительная таблица соединений между людьми и отелями в базе данных. Если вы используете Hibernate, он автоматически сгенерирует эффективное объединение для вас, если вы спросите его о людях в отеле (он присоединится к отелям на rooms.hotel_id для вас).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...