Modeling circular depedencies - java

I am trying to model down the relationship between student and course. Below are the 2 high level queries i need to support down :
Finding all the courses a student is enrolled in
Find all the students enrolled for a course.
The relationship is a M:N relation ship (many to many, i.e. multiple students enroll to multiple courses).
How can i model them in terms of java objects. Intuitively, Student and Course seem to refer each other, creating circular dependency (or back reference).
class Student{
Long id
String name
List<Course> enrolledCourses;
Long rollNumber
}
Course{
Long id
String name
List<Student> enrolledStudents;
}
Is it the right behaviour to model such requirements in the above manner.
I am a little hesitant to create such circular dependencies, but not sure how i can model it otherwise.
Is above the right approach ?
Or does there exist a better way to model these sort of behaviour's ?

If I understand you correctly you're a bit afraid of the redundancy. If Student X visits Course Y, you have Course Y in the student's list of courses and Student X in the course's list of students.
If you pay attention to the modifying methods, this will probably be the best way to model this situation.
But if your fear of ending up with a student visiting a course he wasn't in (according to the course), you'll have to do it like in relational databases and create a relation object.
Now if you think a little more about the situation, there's probably a lot to tell about this course-visit. When did the student visit the course? Did he do any exams? what were the results? Which professor lead this instance of the course? After analysing that, you'll have a much better picture of the situation.
My approach is usually to analyse the situation thoroughly first. Then I analyse my operations on the data. Finally I start thinking about an optimal representation of my data.

This is without problems in Java, and the right approach. A bijective relation, being regularly used in both directions. In JPA they would typically get an annotation to fetch them lazily.
In fact modeling with JPA annotations would allow you to express primary key, many-to-one and such.
I personally would prefer long rollNumber instead of the nullable Long rollNumber.
Of course not always a sensible thing to do, especially when the entities are subordinate.

Related

DDD - Value Object flavor of an Entity

I've seen some DDD projects with value object representations of entities.
They usually appear like EmployeeDetail, EmployeeDescriptor, EmployeeRecord, etc. Sometimes it holds the entity ID, sometimes not.
Is that a pattern? If yes, does it have a name?
What are the use cases?
Are they value objects, parameter objects, or anything else?
Are they referenced in the domain model (as property) or are they "floating" just as parameters and returns of methods?
Going beyond...
I wonder if I can define any aggregate as an ID + BODY (detail, descriptor, etc) + METHODS (behavior).
public class Employee {
private EmployeeID id;
private EmployeeDetail detail; //the "body"
}
Could I design my aggregates like this to avoid code duplication when using this kind of object?
The immediate advantage of doing this is to avoid those methods with too many parameters in the aggregate factory method.
public class Employee {
...
public static Employee from(EmployeeID id, EmployeeDetail detail){...};
}
instead of
public class Employee {
...
public static Employee from(EmployeeID id, + 10 Value Objects here){...};
}
What do you think?
What you're proposing is the idiomatic (via case classes) approach to modeling an aggregate in Scala: you have an ID essentially pointing to a mutable container of an immutable object graph representing the state (and likely some static functions for defining the state transitions). You are moving away from the more traditional OOP conceptions of domain-driven design to the more FP conceptions (come to the dark side... ;) ).
If doing this, you'll typically want to partition the state so that operations on the aggregate will [as] rarely [as possible] change multiple branches of the state, which enables reuse of as much of the previous object graph as possible.
Could I design my aggregates like this to avoid code duplication when using this kind of object?
What you are proposing is representing the entire entity except its id as a 'bulky' value object. A concept or object's place in your domain (finding that involves defining your bounded contexts and their ubiquitous languages) dictates whether it is treated as a value object or an entity, not coding convenience.
However, if you go with your scheme as a general principle, you risk tangling unrelated data into a single value object. That leads to many conceptual and technical difficulties. Take updating an entity for example. Entities are designed to evolve in their lifecycle in response to operations performed on it. Each operation updates only the relevant properties of an entity. With your solution, for any operations, you have to construct a new value object (as value objects are defined to be immutable) as replacement, potentially copying many irrelevant data.
The examples you are citing are most likely entities with only one value object attribute.
OK - great question...
DDD Question Answered
The difference between an entity object and a value object comes down to perspective - and needs for the given situation.
Let's take a simple example...
A airplane flight to your favourite destination has...
Seats 1A, 10B, 21C available for you too book (entities)
3 of 22 Seats available (value object).
The first reflects individually identifiable seat entities that could be filled.
The second reflects that there are 3 seats available (value object).
With value object you are not concerned with which individual entities (seats) are available - just the total number.
It's not difficult to understand that it depends on who's asking and how much it matters.
Some flights you book a seat and others you book a (any) seat on a plane.
General
Ask yourself a question! Do I care about the individual element or the totality?
NB. An entity (plane) can consider seats, identity and / or value object - depending on use case. Also worth noting, it has multiple depends - Cockpit seats are more likely to be entity seats; and passenger seats value objects.
I'm pretty sure I want the pilot seat to have a qualified pilot; and qualified co-pilot; but I don't really care that much where the passengers seats. Well except I want to make sure the emergency exit seats are suitable passengers to help exit the plane in an emergency.
No simple answer, but a complex set of a pieces to thing about, and to consider for each situation and domain complexity.
Hope that explains some bits, happy to answer follow-up questions...

How to avoid loading duplicate objects into main memory?

Suppose I am using SQL and I have two tables. One is Company, the other is Employee. Naturally, the employee table has a foreign key referencing the company he or she works for.
When I am using this data set in my code, I'd like to know what company each employee works for. The best solution I've thought of it to add an instance variable to my Employee class called Company (of type Company). This variable may be lazy-loaded, or populated manually.
The problem is that many employees work for the same company, and so each employee would end up storing a completely identical copy of the Company object, unnecessarily. This could be a big issue if something about the Company needs to be updated. Also, the Company object would naturally store a list of its employees, therefore I could also run into the problem of having an infinite circular reference.
What should I be doing differently? It seems object oriented design doesn't work very well with relational data.
This is more of a design/principles sort of question, I do not have any specific code, I am just looking for a step in the right direction!
Let me know if you have any questions.
Do not try design your business objects to mirror database schema.
Design objects to serve your business requirements.
For example in case when you need to display list of employees without company information, you can create function which retrieve only required information from database to the object
public class EmployeeBasicInfo
{
public int Id;
public string Name;
}
For next requirements you need a list of employees with full information - then you will have function which retrieve full data from database
public class Employee
{
public int Id;
public string Name;
public int Age;
public CompanyBasicInfo Company;
}
Where Company class will not have collection of employees, but will have only information required for Employee class.
public class CompanyBasicInfo
{
public int Id;
public string Name;
}
Of course in last case you end up with bunch of different Company objects which will have same data. But it should be Ok.
If you afraid that having same copy of data in different object will cause a performance problem, it will not until you will load millions of employees - which should be good sign of something gone wrong in your application design.
Of course in situation where you actually need to load millions of employees - then you can use approach that class which loads employees - will first load all companies in the Map<int, Company>, and then when loading employees you will refer same Company instance for employees.
Am I really the only person who is running into this issue? There must be some way to do this without relying on lazy-loading every property.
This problem has been solved many times before already. Avoid re-inventing the wheel by using any of the widely available ORM frameworks.
In a database table, the primary key identifies a record; in a running application, the reference tracks an object; and, at an even lower abstraction, a memory address points to the bytes that represent that object.
When you initialise an object and assign it to a variable, the variable is sufficient to track the object in memory so that you can subsequently access it. However, in the database layer, a primary key is needed to locate the record in a database table. Therefore, to bridge the gap between the relational model and the object model, the artificial identifier property is required in your object.

Making a simple UML class diagram for a school

I'm trying to create a simple class diagram for a school. Within my class-hierarchy, a school typically consist of two main stakeholders (student & teacher) and many students can be assigned to a teacher. May I know how I can show this relationship?
I have used aggregation and enumeration in my class diagram however, I'm not exactly sure if it's correct. Could you please advise me?
Multiplicity: The way you are using multiplicities is correct (as I can foresee it). It means that there must be at least one student per teacher. Without student, there is not teacher. Sounds like a hire and fire school with no permanent teachers.
Aggregation: You may use the shared aggregation (open diamond) the way you did. It's correct but see my remarks below.
Enumeration: Regarding the <<enumeration>> you would just need a dependency rather than an association. Unlike relations to classes an <<enumeration>> is kind of a "primitive" which is not represented as object.
Role names: As #Oguz points out it's a good idea to use role names at the end of the associations. So you would put teacher near Teacher and students (plural because you have 1..*) near Student at the association. These roles would be implemented as attributes.
Additional remarks on shared aggregation:
You must not care much about shared aggregation. As per UML specification it has no common semantics (p. 110 of UML 2.5):
Indicates that the Property has shared aggregation semantics. Precise semantics of shared aggregation varies by application area and modeler.
Aggregation is more about lifetime of objects and real life applications are rather rare than often (mainly if you have to be memory aware in terms of cost or security).
So in your (and most other) case(s) the multiplicity is what you want to show. This is usually more important than showing e.g. a composite aggregation (where the child objects dies with its parent) let alone shared composition.
You can change the aggregation name to students. And In the java code, teacher class has an array, arraylist or set etc. which name is students. And there is one more thing, is this relation 1 to many or 0 to many(0..*)?
public class Teacher extends StakeHolders{
public Student[] students;
public void markAttendance(){
}
}

Bidirectional collection in java

I have Many-to-Many associated entities information with me.
I would like to show the user the list of "students" and if user chooses an student, show his teachers.
Conversely, user may opt to see list of teachers and he/she can select a teacher to see all the students that teacher is teaching.
I am looking to have a java collection class (java built in or 3rd party) to represent such data so that I can query for teachers based on student or vice versa.
Bidi map comes quite close but it enforces 1:1 relationship. I have many to many relationship.
Any clues?
i think you couldn't do that with a map. the most simple way would be, to create a Student class and a Teacher class. both of it could have a method like addTeacher(Teacher teacher) / addStudent(Student student). So each Student objects knows it Teachers and each Teacher object knows it Student.
I am not sure if this is what you are looking for, but you can have a look at Guava BiMap
Does this not suffice?
Map<Student, Set<Teacher>> studentsToTeachers;
Map<Teacher, Set<Student>> teachersToStudents;
It's not a single collection, but it would solve your problem, provided your implementation was correct.

What's the best way to make this Java program? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
This the description of the program brief:
Produce a software that keeps track of courses taught by lecturers at College. For each course, a course code and title needs to be recorded, as well as a list of lecturers taking that course needs to be recorded. The system should allow courses and lecturers to be added and removed from the list and information such as lecturers taking a course and courses registered to a particular lecturer to be displayed.
So far I have two classes Lecturer and Course and they two attributes such as name id, and code and title respectively. I have then created two more classes to hold the data for both of those objects and I have used a Map, so I have mapped id and name for Lecturer and code and title for course, they are both in seperate classes called LecturerList and CourseList.
But now I can't allocate a course to a lecturer. have been stuck on this for a week now. Any ideas? Have I approached this the wrong way?
How about using a map, like:
Map<Course, Lecturer>
or
Map<Lecturer, List<Course>>
I disagree that the problem needs a database. It's the object-oriented part that you're having problems with. Get that right and a database will follow if you need persistence.
I'd start with Course and Lecturer, as you did. Course would have the required code and title attributes, plus a List of Lecturers teaching it. Likewise, Lecturer would have a name attribute and a List of Courses being taught. It sounds like a bi-directional 1:m relationship to me. The language of your problem statement is a bit confusing, but it sounds like a Course can be taught by several Lecturers (perhaps because there are several sections of a given Course), and a Lecturer can teach more than one Course.
If this sounds accurate, I don't think you need a CourseList or LecturerList class.
The problem description is screaming "Database!". This problem is about tracking related sets of information, the very thing database software was designed for. My solution to this problem would be to use mySQL, and the Java database connector for mysql.
Try to make a functional schema (I almost wrote UML) of what you are trying to achieve. Ideally, use a piece of paper, a pencil, and draw boxes for each functional entity (Lecturer, Course, etc), and draw a labeled, oriented line for each type of relationship between these entities. Use colors, if need be.
If you think of the lines you have drawn as pieces of rope, on what such relationships do you need to "pull" to get the lists you are asked for?
Then and only then, try to design the class structure...
I would suggest storing a list of courses within the Lecturer and a list of Lecturers in the Course. Then create a service that models the "system", something like:
Course {
String code;
String title;
List<Lecturer> lecturers = new ArrayList<Lecturer>();
... accessors & other business rules ...
}
Lecturer {
int id;
String name;
List<Course> courses = new ArrayList<Course>();
... accessors & other business rules ...
}
LectureServices {
List<Course> coursesAvailable = new ArrayList<Course>();
addCouse(Course course) {
coursesAvailable.add(course);
}
addLecturerToCourse(Lecturer l, Course c) {
... lookup course ...
c.addLecturer(l);
l.addCourse(c);
}
... etc ...
}
Start with your basic objects and what properties they have
student -> id, name, list of courses
lecturer -> name, list of courses
course -> code, name, list of students, list of lecturers
From your requirements, the course appears to be the major component of interest, so let that be the place to start.
Since a student takes a course (not the other way around), the key function should be an operation on the course [course.addstudent]. But, you also need to be able to list all the courses a specific student is taking, so you need to keep a list by student somewhere, and the student object makes sense [student.addCourse]. Since adding the student to a course and creating the list of courses a student is taking, is a single logical "action", it makes sense to have a single function that handles the entire thing- and I would go back to the course, since it's what your really maintaining, as the place to do that.
The psuedocode isn't be perfect, but you can get the idea:
course.addStudent(student) {
course.listOfStudents.add(student)
student.addCourse(this)
}
student.addCourse(course) { student.listOfCourses.add(course) }
Deleting a student from a course, and adding and deleting the lecturer is similar.
You've used maps to map lecturer and course IDs to attributes? That doesn't sound very object-oriented, and in Java you'll have trouble if you try to not be OO!
This sounds to me like the sort of application where you will want to maintain bidirectional links between Lecturer and Course: i.e. each course has one lecturer --- is that always true? --- so Course has get/setLecturer methods, and each Lecturer has a container of Courses with add/set/remove/getCourse(s) methods. You shouldn't need to maintain external tables to store the Lecturer & Course details, or their mappings: in Java the objects themselves can be stored directly as everything is really a reference.
If this is to be used in anything approaching a production environment then you will want a database and I can recommend the Hibernate object-relational mapping system (especially using annotation-driven persistence) for automating much of the database retrieval, storage, cascading deletion, query pooling strategies, etc. But if this is just a pedagogical exercise, then that will be far too heavy. Oh, and if you're using this in production, maybe having a look at some existing course management / virtual learning environment software: see the bottom of http://en.wikipedia.org/wiki/Virtual_learning_environment for some references.

Categories