title: How do I model something like this? (section-teacher relationship)
body: <p>I have this homework that I gotta finish, but then something about it is really bugging me. I've been thinking about this, but I think my approach is flawed. Well, it really is, since I tried it, and it just gave me a stackoverflow exception thingy. Anyhow, here is a snippet of the specs that was given to me by the mentor:</p>
  
  <blockquote>
    <ul>
    <li>A section is defined as a combination of a teacher, a subject and a
    schedule.<br> </li>
    <li>A section can accommodate a maximum of forty (40) students. <br></li>
    <li>Each subject is worth three (3) units. A teacher is identified by
    his/her Faculty ID. </li>
    <li>A teacher cannot teach two sections with the same schedule.</li>
    </ul>
  </blockquote>
  
  <p>My teacher class has a list of sections that he/she teaches. I was planning that if I create a section, the constructor would have to check first if the schedule of that section conflicts with the one on the list. If there was no conflict, then the section is successfully created and that section will have to be added to the list of sections that the teacher has. I guess my logic is ok, but the my implementation is not! </p>
  
  <p>Here is the class that I created based on the description above:</p>
  
  <pre><code>import java.util.List;
  
  import org.apache.commons.lang3.Validate;
  
  public class Section {
  
      //A section is defined as a combination of a teacher, a subject and a schedule.
      private Teacher teacher;
      private Subject subject;
      private Schedule schedule;
  
      private String sectionName;
  
      //A section can accommodate a maximum of forty (40) students.
      private int numOfStudentsItCanAccomodate = 40;
  
      public Section(Teacher teacher, Subject subject, Schedule schedule,
              String sectionName){
  
              this.teacher = teacher;
              this.subject = subject;
              this.schedule = schedule;
              this.sectionName = sectionName;
  
              Validate.notNull(teacher,"Teacher field"+Prompts.FAILED_PROMPT_NULL.getMessage());
              Validate.notNull(subject,"Subject field"+Prompts.FAILED_PROMPT_NULL.getMessage());
              Validate.notNull(schedule,"Schedule field"+Prompts.FAILED_PROMPT_NULL.getMessage());
              Validate.notNull(sectionName,"Section name"+Prompts.FAILED_PROMPT_NULL.getMessage());
  
              Validate.notBlank(sectionName,"Section name"+Prompts.FAILED_PROMPT_BLANK.getMessage());
  
              if(sectionConflictsWithTeachersOtherSections(teacher,schedule)==true){
                  throw new IllegalArgumentException(Prompts.FAILED_PROMPT_TEACHER.getMessage());
              }else{
                  //**I believe this line faulty** No! It is faulty and stupid of me. T_T
                  teacher.addSection(new Section (teacher,subject,schedule,sectionName));
  
              }
      }
  
      public Teacher getTeacher() {
          return teacher;
      }
  
      public Subject getSubject() {
          return subject;
      }
  
      public Schedule getSchedule() {
          return schedule;
      }
  
      public String getSectionName() {
          return sectionName;
      }
  
      //A teacher cannot teach two sections with the same schedule.
      private boolean sectionConflictsWithTeachersOtherSections(Teacher teacher,Schedule newSchedule){
          boolean conflict = false;
          List&lt;Section&gt; teachersListOfSections = teacher.getListOfSections();
  
          if(teacher.getListOfSections().size()&gt;0){
          for(Section takenSection:teachersListOfSections){
              Schedule scheduleOfTakenSection = takenSection.getSchedule();
  
              if(scheduleOfTakenSection.getDay().equals(newSchedule.getDay()) &amp;&amp;
                  scheduleOfTakenSection.getTime().equals(newSchedule.getTime())){
                  conflict = true;
                  }
              }
          }
  
          return conflict;
      }
  
      public void subtractNumOfStudentsItCanAccomodate(){
          this.numOfStudentsItCanAccomodate--;
      }
  
      public int getNumOfStudentsItCanAccomodate() {
          return numOfStudentsItCanAccomodate;
      }
  
      @Override
      public int hashCode() {
          final int prime = 31;
          int result = 1;
          result = prime * result + numOfStudentsItCanAccomodate;
          result = prime * result
                  + ((schedule == null) ? 0 : schedule.hashCode());
          result = prime * result
                  + ((sectionName == null) ? 0 : sectionName.hashCode());
          result = prime * result + ((subject == null) ? 0 : subject.hashCode());
          result = prime * result + ((teacher == null) ? 0 : teacher.hashCode());
          return result;
      }
  
      @Override
      public boolean equals(Object obj) {
          if (this == obj)
              return true;
          if (obj == null)
              return false;
          if (getClass() != obj.getClass())
              return false;
          Section other = (Section) obj;
          if (numOfStudentsItCanAccomodate != other.numOfStudentsItCanAccomodate)
              return false;
          if (schedule == null) {
              if (other.schedule != null)
                  return false;
          } else if (!schedule.equals(other.schedule))
              return false;
          if (sectionName == null) {
              if (other.sectionName != null)
                  return false;
          } else if (!sectionName.equals(other.sectionName))
              return false;
          if (subject == null) {
              if (other.subject != null)
                  return false;
          } else if (!subject.equals(other.subject))
              return false;
          if (teacher == null) {
              if (other.teacher != null)
                  return false;
          } else if (!teacher.equals(other.teacher))
              return false;
          return true;
      }
  
      public boolean conflictsDayWith(Section newSection){
          return (this.schedule.getDay().equals(newSection.schedule.getDay()));
      }
  
      public boolean conflictsTimeWith(Section newSection){
          return (this.schedule.getTime().equals(newSection.schedule.getTime()));
      }
  }
  </code></pre>
  
  <p>My teacher class:</p>
  
  <pre><code>public class Teacher extends Person{
  
      private List&lt;Section&gt; listOfSections;
  
      public Teacher(String firstName,String lastName, String middleName)
                      throws IllegalArgumentException{
          this.firstName = firstName;
          this.lastName = lastName;
          this.middleName = middleName;
          this.listOfSections = new ArrayList&lt;Section&gt;();
  
          Validate.notNull(firstName, "First name "+Prompts.FAILED_PROMPT_NULL.getMessage());
          Validate.notNull(lastName, "Last name"+Prompts.FAILED_PROMPT_NULL.getMessage());
          Validate.notNull(middleName, "Middle name"+Prompts.FAILED_PROMPT_NULL.getMessage());
      }
  
      public void addSectionToList(Section newSection){
          listOfSections.add(newSection);
      }
  
      public void teachesSection(Section newSection){
          this.listOfSections.add(newSection);
      }
  
      public List&lt;Section&gt; getListOfSections() {
          return listOfSections;
      }
  
      @Override
      public int hashCode() {
          final int prime = 31;
          int result = super.hashCode();
          result = prime * result
                  + ((listOfSections == null) ? 0 : listOfSections.hashCode());
          return result;
      }
  
      @Override
      public boolean equals(Object obj) {
          if (this == obj)
              return true;
          if (!super.equals(obj))
              return false;
          if (getClass() != obj.getClass())
              return false;
          Teacher other = (Teacher) obj;
          if (listOfSections == null) {
              if (other.listOfSections != null)
                  return false;
          } else if (!listOfSections.equals(other.listOfSections))
              return false;
          return true;
      }
  
      @Override
      public String toString(){
          return firstName + " " + middleName + " " + lastName ;
      }
  }
  </code></pre>