2010-04-11 2 views
7

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

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

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

Я сделал схему для иллюстрации:

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

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

Спасибо.

ответ

4

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

interface IPerson 
    IRoom getRoom() 
    // etc 

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

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

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

+1

Я вижу, что «взаимная зависимость» - это то слово, которое я искал. Для записи я пишу это на Java. Интерфейсный подход кажется интересным, но не делает решение гораздо более различным, но я понимаю вашу точку зрения. Спасибо за ваш комментарий. –

+2

@ Kasper, point is, нет реальной проблемы с наличием зависимостей от _interfaces_ (включая взаимные) - это в основном зависимости от программного обеспечения _concrete_, которое вы действительно хотите избежать (например, в случае «циклов»). Свобода начать с быстрой и грязной реализации и переключиться на эхолот позже также ускоряет прототипирование и итерацию программного обеспечения в процессе его эволюции и обслуживания. –

9

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

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

+0

Я понимаю, что вы говорите, что есть недостаток в моей логике, спасибо, что указали это! Однако я думал, что HashMap, содержащий имя пользователя, и Person-объект будет быстрее для поиска пользователя, чем повторение через «Комнаты». –

+4

Я очень ценю вашу похоть за миллисекунды, поскольку я разделяю эту страсть - но удивительный OOP - это более быстрое/чистое чтение и запись кода, а не более быстрое время выполнения. Я бы предложил вам попробовать в обоих направлениях и времени - различия, вероятно, не будут такими большими, как вы думаете. (Если вы сделаете это, разместите свои результаты для нас!) –

+0

Ты меня достал! Этот комментарий о похоти за миллисекунды. Вы дали мне что-то подумать, спасибо :) –

1

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

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

+0

Для справки, я согласен с тем, что кэширование их как собственности отеля, вероятно, не самый лучший способ сделать это. Лично я бы тоже перебирал;) –

+0

Что бы вы назвали переменные-члены в Person, так что это было бы скорее ссылкой? Предположим, что у меня огромное количество пользователей, и что мне нужно искать одного пользователя. Что было бы лучше всего? Я знаю, что сохраняю избыточную информацию в ссылках. Эти классы используются только вместе (Есть еще пара, но не так много). –

0

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

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

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

Смежные вопросы