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.
Related
I have an application of POJOs (plain old java objects) representing my data.
While running, the application manipulates and remembers data as desired.
Now I want to implement a save/load feature.
I am NOT asking about basic file I/O.
I am NOT asking whether ObjectOutputStream exists.
Options I have found are those such as:
1) JSON/XML/YAML libraries such as Gson, Jackson
2) Roll your own binary file format marking everything as Serializable with a Serialization Proxy pattern.
Option 1 is unsuitable because my data model can feature cyclic references. Gson resulted in a stack overflow.
Option 2 is unsuitable because the files should be cross platform and independent of JVM; it should work on desktop and android java.
A properties file is also obviously unsuitable due to the complexity of the model.
Please do not attack my use case; my data model is perfectly well designed. The example may not be.
I will now give example code of the kind of structure that needs to be saved.
class Application {
//This College is my top level object. It could correspond to an individual save file.
College college = new College();
//I would love to be able to just throw this guy into a file.
SomeLibrary.writeToFile(college);
//And read another back.
College college2 = SomeLibrary.readFromFile(anotherCollege);
}
class College {
//The trees are implemented recursively, so this is actually just the root of each tree.
Tree<Course> artCourseTree;
Tree<Course> engineeringCourseTree;
Tree<Course> businessCourseTree;
List<Student> maleStudents;
List<Student> femaleStudents;
}
class Course {
//Each course only has 2 students in this example. Ignore.
Student student1;
Student student2;
List<Exam> examsInCourse;
LocalDate courseStartDate;
Period duration;
}
class Student {
String name;
List<Exam> listOfExamsTaken;
}
class Exam {
Student studentTakingIt;
LocalDate dateTaken;
BigDecimal score;
}
As you can see, Exams are intended to be the atomic object in this model at the bottom of the hierarchy. However, not only are they referenced by both Students and Courses, but they also refer back up to a Student and contain nonprimitives such as LocalDate and BigDecimal. The model is given meaning by referencing different subsets of Exams in different Courses and Students.
I need to save the relationships, the arrangement of these things, an arbitrary number of these things, as well as the data they hold.
What hope do I have of saving and loading such a model?
What options are there to implement a save/load feature on such a model, with such constraints?
Is it really industry standard for every java program to roll its own binary file format and create a monstrous apparatus to serialize and deserialize everything? It's that or JSON? What am I missing here? Do I have to just snapshot the VM somehow? Why is there not a standard practice for this?
Circular references is a common use case and can be handled by providing #JsonManagedReference or #JsonBackReference. Check out this SO answer for more details. Another option is to implement custom serializer and solve circular references by yourself. Here is the example for the same.
However, do consider the following aspects before going ahead with using files as database
You will have to manage concurrent writes by yourself. If not correctly handled might result in corruption/loss of the data because files are not ACID compliant by nature.
The solution is not scalable as file size will grow. Time to serialize and deserialize will increase proportionately.
You won't be able to query easily on the data stored in the file. You will always have to deserialize data first and then query on POJOs.
I'll highly recommend checking SQLite which is small, fast, self-contained, high-reliability, full-featured, SQL database engine.
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.
I just started coding in Java and my professor is not the best and teaching it. We were assigned a program that I vaguely understand. I'd really like to understand how it works and how I should look at the problem. Ex. how do I create a department, then store professors in it, leave and make more departments and such, then come back and retrieve the professors from other departments. I don't understand how I am supposed to do that in Java. If anyone could help a beginner out that would be great. Thanks.
Picture of my assignment:
A Java class is just a template for a structure with some properties and some methods. An instance of such a class would be called an object. One of those properties may reference other objects, like this:
class Department{
Set<Professor> profs= new HashSet<>();
}
class Professor{
}
Now, if you want to make two (unnamed) Departments and add some (unnamed) Professors to it, you would add:
Department[] aDep= new Department[new Department(), new Department()];
aDep[0].profs.add(new Professor());
aDep[1].profs.add(new Professor());
aDep[1].profs.add(new Professor());
After this, the first Department would have one Professor, the second two.
I have made an aggregate class named Question. This contains references to Answer, Category, Feedback objects. Should the QuestionRepository be the class that contains all methods quering the database that relates to the Question but also all the methods for quering the Feedback, Answer etc? Or should these be seperate classes such as QuestionRepository, FeedbackRepository and so on.
From the way you have explained , I am assuming that each Question will have 1 or more Answers , 1 or more Feedback and the Question belongs to a particular Category
Since the Answer and Feedback are dependent on Question and cannot exist independently , you can have a single QuestionRepository for these 3 entities .
Coming to Category , category is more of a static entity which IMO is a static list , so all such static entities can be grouped together in a StaticRepository
From the DDD web site :
For each type of object that needs global access, create an object
that can provide the illusion of an in-memory collection of all
objects of that type.
A repository is used when you need direct access to an entity, i.e. when there's no other convenient way to get hold of that entity than fetching it from a persistent store directly. In contrast, if you consider that the entity is most of the time easily obtainable through traversal of another object you've already got at hand, then there's no need for a repository. It seems to be the case with Answer, Category, and Feedback here.
Usually repositories are only for aggregate roots, though there may be exceptions.
I suggest you read the DDD blue book or some tutorial to get a basic comprehension of the DDD building blocks before you start building your domain model.
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.