Моделирование связанных объектов - PullRequest
3 голосов
/ 30 сентября 2008

Я разрабатываю приложение, которое работает с двумя наборами данных - пользователями и областями. Данные читаются из файлов, созданных третьей стороной. У меня есть класс User и класс Area, и данные считываются в массив Users и массив Areas (или другую подходящую структуру памяти, в зависимости от технологии, с которой мы работаем).

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

Требования довольно просты:

  • Список пользователей
  • Список областей
  • Список пользователей для указанной области
  • Список областей для указанных пользователей

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

Затем я подумал о наличии метода «Get Areas» в классе User и члена «Get Users» в классе Area, который был бы более полезен, если, например, я нахожусь на этапе, когда у меня есть объект Area, Я мог бы найти его пользователей по свойству, но тогда как бы метод «Get Users» в классе Area узнал о / имел доступ к массиву Users.

Я сталкивался с этой проблемой несколько раз, но так и не нашел окончательного решения. Может быть, я просто усложняю, чем на самом деле. Кто-нибудь может дать какие-нибудь советы, URL-адреса или книги, которые помогли бы мне с таким дизайном?

UPDATE: Спасибо всем, что нашли время, чтобы оставить несколько советов. Ваши комментарии очень ценятся.

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

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

Ответы [ 7 ]

7 голосов
/ 30 сентября 2008

это действительно отношения многие ко многим,

User <<--->> Area

разбить его на 3 объекта: Пользователь, Область и Область пользователя:

User: Id, name, etc.
Area: Id, name, etc.
UserArea: UserId, AreaId
3 голосов
/ 30 сентября 2008

Очень простой, но идея такова:

struct/class Membership
{
   int MemberID;
   int userID;
   int areaID;
}

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

РЕДАКТИРОВАТЬ: Другой вариант

Вы можете хранить в каждом Участнике список областей, а в каждой области - список участников.

в области:

public bool addMember(Member m)
{
   if (/*eligibility Requirements*/)
   {
      memberList.add(m);
      m.addArea(this);
      return true;
   }
   return false;
}

и аналогичная реализация в Member (без обратного вызова)

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

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

Я думаю, что первая реализация более дружественна к LINQ.

2 голосов
/ 30 сентября 2008

Область принадлежит нескольким пользователям? Если да, то формально это отношения многие ко многим. Если бы вы преобразовали данные в реляционную базу данных, вы бы создали таблицу со всеми связями. Я думаю, если вы хотите работать с массивами, вы можете создать третий массив. Или, если вы действительно хотите сделать это ОО-способом, оба класса должны иметь массивы указателей на связанные области / пользователей.

1 голос
/ 30 сентября 2008

Извините, но это не объектно-ориентированная проблема. Это проблема отношений. Отсюда и все ссылки на количество элементов (многие ко многим). Это моделирование реляционных баз данных 101. Я не хочу критиковать Гэвина, просто чтобы указать на новую перспективу.

Так что же хорошего в моей напыщенной речи? Ответ должен заключаться в интеграции с хранилищем реляционных данных, а не в превращении его в объектно-ориентированную парадигму. Это классический квадратный колышек с круглым отверстием.

0 голосов
/ 30 сентября 2008

Согласен с дакракотом

Также посмотрите на DevExpress XPO

0 голосов
/ 30 сентября 2008

Одним из вариантов является использование словаря для каждого из последних 2 требований. То есть Dictionary<Area, List<User>> и Dictionary<User, List<Area>>. Вы можете создать их, как вы читаете в данных. Вы можете даже обернуть класс вокруг этих двух словарей и просто иметь метод для этого класса для каждого из требований. Это позволит вам обеспечить синхронизацию словарей.

0 голосов
/ 30 сентября 2008

Почему бы не использовать DataTables с отношениями, если задействован .NET? Возможно, вы захотите взглянуть и на Generics, опять же, если задействован .NET.

...