Как наиболее эффективно обновлять данные в двух взаимозависимых классах

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

У меня есть класс «Студент» и класс «Курс». Студент должен знать все свои курсы, которые он посещает, по списку курсов, а курс должен знать всех студентов, которые его посещают, по списку студентов.

Теперь предположим, что я хочу, чтобы студент посетил новый курс, поэтому я создаю метод «addCourse(курс курса)», чтобы добавить новый курс в список курсов студента — нет проблем. Но я также хочу, чтобы курс знал о том, что студент посещает его сейчас. Поэтому я создаю метод «addStudent (Студент)» для класса курса и вызываю его в методе «addCourse» студента.

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

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


person Froxx    schedule 21.12.2015    source источник


Ответы (1)


У вас есть класс Student с методом AddCourse, который обновляет список курсов, которые посещает учащийся.

У вас есть класс Course с методом AddStudent, который обновляет список учащихся, посещающих курс.

Где-то еще в вашей программе вы решаете, что учащийся собирается посетить курс. Например, может быть пользовательский интерфейс, с которым взаимодействует студент, если он хочет присоединиться к курсу. Это действие пользователя должно инициировать вызов некоторой бизнес-логики, которая делает все необходимое для добавления учащегося в курс. Например:

function AddStudentToCourse(studentId, courseId)
{
    student = GetStudentById(studentId);
    student.AddCourse(courseId);
    course = GetCourseById(courseId);
    course.AddStudent(studentId);
}

Дело в том, что что касается Student, он просто поддерживает список номеров идентификаторов курса. Класс Student на самом деле ничего не делает с курсами; он просто поддерживает список, чтобы какой-нибудь другой фрагмент кода мог ссылаться на него позже.

То же самое для Course; он просто поддерживает список идентификационных номеров студентов.

Прелесть этого дизайна в том, что Student и Course независимы друг от друга, за исключением этих списков идентификаторов; и это действительно просто цифры.

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

person Jim Mischel    schedule 21.12.2015
comment
Я полностью согласен с первой частью вашего решения, т.е. хорошо иметь два метода add... и отдельный метод для создания двунаправленной связи. Однако я бы предложил использовать ссылки вместо идентификаторов. Они менее подвержены ошибкам, требуют меньше места (предполагая, что «целое число» в Java), и их намного легче перемещать. Я бы не беспокоился о «затоплении» вашей памяти, эти двунаправленные ссылки действительно не должны быть проблемой. - person TilmannZ; 22.12.2015
comment
@TilmannZ: Как вы предпочитаете. Однако обратите внимание, что integer составляет 32 бита. Ссылка будет 32-битной в 32-битной системе и 64-битной в 64-битной системе. Хотя, вероятно, это не имеет значения, если только вы не говорите о сотнях миллиардов записей. - person Jim Mischel; 22.12.2015
comment
Я в основном согласен. Если вы скомпилируете для 64-битной версии, вы получите 64-битные указатели. Если вы скомпилируете для 32-битной версии (ограничено 4 ГБ или около того, вы получите 32-битные ссылки, даже в 64-битных системах (я думаю). Java немного отличается, так как ссылки Java compresses требуют только 32-битных, если вы выбрали менее 32 ГБ памяти. , даже на 64-битной JVM. - person TilmannZ; 23.12.2015
comment
Интерфейс — простая, но отличная идея, которая звучит логично, если подумать еще раз. Учащийся не присоединяется к курсу напрямую, а регистрируется на нем, используя форму или что-то в этом роде. Итак, форма устанавливает соединение. - person Froxx; 08.01.2016