Как правильно выбрать структуру данных Java для моделирования реляционного отображения 1-n? - PullRequest
3 голосов
/ 20 мая 2009

Сценарий

Я собираюсь быть кратким, насколько это возможно. В основном со ссылкой на этот classdiag , у меня есть фасад, который управляет списком SocketManager (который управляет одним соединением Socket). Каждый SocketManager входит на удаленный сервер, используя уникальный SocketUserId . Кроме того, каждый SocketManager будет принимать сообщения от клиентов, предназначенных для определенного списка Получатели . Для обсуждения рассмотрим эти Получатели просто как удаленные области данных, идентифицируемые по имени.

Клиенты будут отправлять данные следующим образом:

SocketFacade facade = ...;

byte[] data = ...

facade.sendData( receipient, data );

Когда SocketFacade запускается, он запрашивает таблицу mysql, которая возвращает 1-м соотношение между SocketUserId и Receipients . Я буду использовать MultiValuedMap , чтобы представить это 1-м отношение. Несколько SocketManager будут запущены путем перебора карты.

(1) Map< SocketUserId, List<Receipient> > 

например. Предположим, у нас есть 2 SocketManager с SocketUserId с "Алиса" и "Том" соответственно

            +----SocketManager1 ( "alice" ) for Receipients { "B", "C" }
            |
 SocketFacade 
            |
            +----SocketManager2 ( "tom" ) for Receipients { "A", "D" }

Вопрос

Я не знаю, как реализовать метод sendData . По сути, мне нужен способ сопоставления получателя (например, «B») с ответственным SocketManager (например, SocketManager1 ).

Давайте предположим, что я делаю это

(2) Map< SocketUserId, SocketManager >
(3) Map< Receipient, SocketUserId >
  • Нужно ли SoftReference для значения в (2)?
  • Должен ли я просто сопоставить Получатель непосредственно с SocketManager ?
  • SocketFacade также поддерживает методы, которые изменят отношение, представленное (1). Если я запишу в базу данных, структуры данных в памяти (1), (2) и (3) должны будут синхронизироваться. SocketFacade также должен быть поточно-ориентированным. Первоначальная идея состоит в том, чтобы иметь какую-то систему подписки на публикацию, при которой добавление / удаление в БД приведет к распространению изменений через обратные вызовы.

    interface Callback
    {
        void receipientAdded( Receipient r );
        void receipientDeleted( Receipient r );
    }
    

Ответы [ 3 ]

1 голос
/ 20 мая 2009

Поскольку у вас есть отношение 1-1 между SocketUserId и SocketManager, вы не можете просто добавить ссылку на SocketUserId в SocketMananger и ссылку на SocketManager в Получателе?

Тогда на вашем фасаде будет одна Карта, содержащая получателя и Список SocketManager. В функции sendData вы получите получателя с карты и получите от этого получателя ссылку на его SocketManager.

С уважением

Гийом

1 голос
/ 22 мая 2009

На абстрактном уровне у вас есть: 1 Thing, что относится к n OtherThing с. Вы можете смоделировать это, создав специальный объект отношения, который ссылается на Thing и содержит java.util.List<OtherThing> ссылок на n OtherThing s. Это оставляет ваши доменные объекты (Вещи) незагрязненными информацией об отношениях. Но если это кажется правильным, проще добавить java.util.List непосредственно в класс Thing (или подкласс). Переменная List может быть оставлена ​​пустой и заполнена java.util.ArrayList<OtherThing> только тогда, когда вам нужно установить связь.

1 голос
/ 20 мая 2009

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

В SocketManager сохраните список Receipient. По мере добавления и удаления Receipient обновите указатель до SocketManager.

В SocketFacade вам нужна карта, которая берет SocketUserId и возвращает SocketManager. Эта карта заполняется путем запроса идентификаторов на карте. После того, как все менеджеры существуют, добавьте получателей к каждому. Это занимает два SQL-запроса.

Это очень легко сопоставить с любым инструментом ORM.

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