How would you decouple a scenario of lessons and students? - oop

Assume you are making a software that manages classes and students.
I'd assume you would have an administrator class, lesson class, and student class.
The administrator class can have various functions such as "get the list of all available lessons" or "get the list of all lessons that a student is enrolled in".
Here's the tricky part.
A lesson can have many students while a student can have many lessons.
Here are some implementations I have thought of:
Lesson class contains list of students and student class contains list of lessons:
Pro: Straightforward, Con: Coupled
Lesson class contains list of students and in order to do "get all lessons a student is enrolled in" the administrator class would first get all lessons and then filter lessons containing that student.
Pro: Not coupled, Con: Inefficient computing
In the administrator class, have the following fields :
HashMap<Lesson, [Student]>
HashMap<Student, [Lesson]>
Pro: Not coupled, Con: Messy
None of them seem satisfying to me. Can I get some feedback on this dilemma? What is the typically accepted design pattern?

I wouldn't have the complete Student object inside Lesson objects and vice versa.
Lesson class contains a Set of studentIds of the subscribed students
Student class contains a Set of lessonIds in which they are subscribed to.
Your Administrator class can use these Ids to map, filter, retrieve lessons, students and their relationships.
Edit:
I have to say, that in a real life scenario where your data would be persisted for example in a relational database, you should have a table Students, a table Lessons and a table StudentsLessons with studentId and lessonId as foreign keys.

This is how I would go about it considering the fact that in future I might need to persist them in the DB.
The relationship between student and lesson is many-to-many and hence you need to setup bi-directional
or unidirectional relationship with these two classes.
Bi-directional - List of lessons in Student class and vice versa
Unidirectional - Either list of lessons in Student or list of
students in Lesson class
For example sake, I am setting unidirectional relationship
class Student {
private List<Lesson> lessions;
// other attributes
}
class Lesson {
// Lesson attributes
}
The Administrator class you are talking about is actually a good candidate for service class because it's providing services
such as "get the list of all available lessons"
For Lesson related queries, I'll create LessonService
class LessonService {
// Get the list of all available lessons
List<Lesson> findAllLessons() {...}
// Get all lessons a student is enrolled in
List<Lession> findAllLessons(Student student) {...}
}
and finally, there would a repository/dao layer that will abstract underlying database.
Your repository could be a simple collection based in-memory or represent the actual database.

Related

Mapping UML Association class to Java Model code

I would like to know the proper way to implement UML association class in Java programming code. I have Student and Course classes. Student can attend one or more Courses, Courses can be attended by one or more Student (many-to-many relationship). If I don't have any attribute in association class (despite course and student ids), would it be okey to implement it this way: public class Course{ private List<Student> students ...} public class Student{ private List<Course> course}. Please explain me both situations, because I don't get it if I should have model public CourseEnrollment { private Student; private Course; private LocalDate enrollementDate} and lists of CourseEnrollments in Student and Course classes.
What I tried is explained above with CourseEnrollment class and my doubts.
One easy way to implement an association class is to use a Collection<CourseEnrollment> e.g. an ArrayList<CourseEnrollment>, in both Course and Student, and make sure that CourseEnrollment has a property back to the respective Course and Student.
The navigation would then be indirect: Student -> List of enrolments -> corresponding courses, or Course -> List of enrolments -> corresponding students. The challenge in your code will be to maintain consistency, e.g. if your remove a student from a course, you'll need not only to delete the enrollment from the course's collection, but also from the student's collection.
Another alternative is to use an independent repository of CourseEnrollments, that keeps a list of all the enrolments and provides efficient access for a student and a course, through two HashMap. The advantage is that there's only one place to manage the enrollment, and students or courses can get the relevant and up-to-date links from there. Again, navigation is indirect, this time by querying the repository. The challenge here is to manage decoupling, since every Student or Course would need to know about the repository.
You may have noticed, that in both cases, the trick is to implement the association class as a class, and to decompose the direct association between Student and Course into an indirect association via the association class.
P.S: In the UML semantics, the association class is at the same time a class and an association. But it can have only one name. Chose either chooses or CourseEnrollment, but you should not use different names.

In Prisma, how do I create a many-to-many relationship but one side of the relationship creates unique instances of the other side?

Let's say we are creating an LMS with Students and Exercises.
The Students have many exercises and each exercise has many users...BUT... I want to put a "isComplete Boolean?" on the exercise model and have each student be able to know if they completed that exercise or not.
I know this is a super simple problem, I have been banging my head and cannot for the life of me figure out how to model these!
model Student {
name String
exercises Exercise[]
}
model Exercise {
title String
description String
isComplete Boolean #default(false)
students Student[]
}
That sounds to me like a use case for an explicit many-to-many relation: https://www.prisma.io/docs/concepts/components/prisma-schema/relations/many-to-many-relations#explicit-many-to-many-relations
You can then add this attribute to the third table that connects students with exercises.

Understanding abstract class OOD -> relational schema [duplicate]

I have the below UML class diagram with Abstract Class, and sub-Classes that extends from it. and i want to make an ER diagram using this class diagram.
My question is how can i represent the Abstract class in ER diagram ? as a Table ? or should i just ignore it ?
Thank you.
There are basically three choices to translate generalization into a database model
1. One table per concrete class
Create tables Admin, Teacher and Student. Each of these table contain columns for all of the attributes and relations of User
Pro
All fields of a concrete subclass are in the same table, so no join needed to get all Student data
Easy data validation constraints (such as mandatory fields for Student)
Con
All fields of User are duplicated in each subclass table
Foreign keys to User have to be split into three FK fields. One for Admin, one for Teacher and one for Student.
2. On table for whole generalization set
In this case you just have one table call User that contains all fields of User + all fields of all sub-classes of User
Pro
All fields are in the same table, so no join needed to get all User data
No splitting of FK's to User
Con
There are a bunch of fields that are never used. All fields specific for Student and Teacher are never filled in for Admins and vice versa
Data validation such as mandatory fields for a concrete class such as Student become rather complex as it is no longer a simple Not Null constraint.
3. One table per concrete class, and one for the superclass
In this case you create tables for each of the concrete sub-classes and you create a table for the class User. Each of the concrete sub-class tables has a mandatory FK to User
Pro
Most normalized schema: No repeated fields for the attributes of user, and no unused fields.
No splitting of FK's to User
Easy data validation constraints (such as mandatory fields for Student)
Con
You have to query two tables if you want all data of a Student
Complex validation rules to make sure each User record has exactly one Admin, Teacher or Student record.
Which one of these options you choose depends on a number of things such as the number of sub-classes, the number of attributes in either subclass or superclass, the number of FK's to the superclass, and probably a few other things I didn't think about.

New to Object Oriented Design

I am new to object oriented design. I am looking forward to some tips on how to model the below mentioned requirement using objects.
Requirement: A program has many Students. A program logs in to the application. First page displays a table of all the Students belonging to the program (Table Columns - Id, First name, last name, age, sex, etc. ). The Id is a link. By clicking the Id, the individual student page is displayed. In this page, an individual student related activities can be done - for eg. edit address, change name, add comments etc.
My Solution: Two Classes
Program - Will model a single program, perform all activities related to it and encapsulate all program related db tables.
Student - Will model a single student and perform all activities related to it and encapsulate all student specific db tables.
So far, so good.
In order to fetch details of all students related to a program, from Program object I need to call a method called 'fetch_student_details'.
The Question is where should this method be written? Should it be a Student Class method or Program Class method.
If I write this method in program class, how will the Program class handle it?
(a) First identify the list of student_ids that belong to it and for each id, instantiate a Student Class and get the specific student related information from it. DB: Each instantiated student object will run a query to fetch its information. So 100 students, 100 queries.
OR
(b) Fetch the list of student ids related to the program and fetch the student information directly for all the students. Db: Single query to fetch all the needed information.
In this case, if you can, go for solution (b). Students and Programs, in fact, are two differet entities that can exist independently, and you don't break encapsulation.
With solution (a) you need to pollute Program's interface by adding a method for each possible information that you want to get from the Students.
As final suggestion, if you want to learn OO Design, start by reading the book "Design patterns - Elements of Reusable Object-Oriented Software" by Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides (AKA "The gang of four").

Entity Relationship Model: Ternary Relationships

I am trying to understand why this statement in the book is wrong: "given a C entity, there is at most one related A entity and at most one related B entity".
Is it that it doesn't apply to a specific kind of relationship??
So, if I have an example of a student who is in attendance to a course with a type of subject. The entities are student, attendance, course and subject. Student makes attendance in a room. Also, a student can make attendance for a subject. Does this example apply to the statement?
Thanks for your time.
The author probably means: in a single relationship instance (e.g., student-Bob/course-ABC/attendance123). So there is a single student, a single course and a single attendance record linked in that instance.
Not across all relationship instances in the class (where student Bob could attend many classes over time).