0

Suppose we want to model students which attend courses. Every student should attend at most one course at a time and a course can contain multiple students (a typical 1-to-n association). Suppose further that this association should be bidirectional, i.e. we should be able to navigate from student to course and vice versa.

So naturally we would have two classes, Student (holding a reference to the assigned course) and Course (containing a collection of students). But how do we compose the object graph? Specifically, which operations on which classes should we define to establish a link between a student and a class? The first obvious option would be to define a generic Add method on the Course class:

class Course
{
    public void Add(Student student) { ... }
}

But you could equally define an operation on the Student class instead:

class Student
{
    public void Attend(Course course) { ... }
}

(Surely there are more options, like passing an instance of the Course class to the constructor of Student, but that is not the point here)

Comparing these two alternatives, personally I find the second option more attractive because student.Attend(course) conveys more information than course.Add(student), since Attend has more meaning than the generic Add. However I have not yet encountered a single API which uses this style of adding an element to a container object, which leads me to the conclusion that I am missing something important.

So, except that the second option is not very common, what are its drawbacks? Or is it not as uncommon as I think it is?

proskor
  • 1,382
  • 9
  • 21
  • From the point of common sense, student can attend course, and course shouldn't add students. From the point of practice, there will be public properties `Student.Course` and `SomeCollectionType Course.Students`, and sometimes relation will be established using `Student.Course` initialization, sometimes - using `Course.Students.Add(student)`. – Dennis Dec 25 '14 at 14:29
  • "Every student should attend at most one course at a time" means it takes a long time to graduate or that a student may enroll in several courses, but ought not to commit to being in two different places at the same moment? And what about students who _audit_ a course? – HABO Dec 25 '14 at 14:43
  • 2
    Course can have meaningful methods to register a student. What are you dealing with, are you dealing with courses or students, if your main point of view is students, then put the student in the center of your design. – hazimdikenli Dec 25 '14 at 15:01
  • @hazimdikenli Didn't come up with the `Register` operation on the `Course` class... Thanks for the tip. – proskor Dec 25 '14 at 15:10
  • If "Attendence" is a concern for you then maybe it should be an entity in your model? – Onots Dec 26 '14 at 00:50

1 Answers1

0

In most circumstances it would be rather unrealistic to assume that a Student will be able to attend a Course without fulfilling any requirements established by the Course.

A more complete protocol would start with a Student applying to a Course. Then the Course would accept or reject the application and act accordingly by registering the Student or not and notifying them the decision, whatever it had been.

If the Student receives the acceptance response, they might opt for "taking note" of the Course that accepted the application. This action would be just for the Student's convenience because the formal steps had already been accomplished. Thus, if we agree that it is up to the Student to keep track of the courses they attend (in the present and past) it becomes pretty clear that the attend method is not mandatory and therefore should not be the main one.

Leandro Caniglia
  • 14,495
  • 4
  • 29
  • 51