Beginner 30 min read

Add Business Rules

By the end of this lesson, you'll be able to:

  • Enforce a maximum roster size before allowing enrollment
  • Prevent the same student from being enrolled twice
  • Explain why business rules belong inside the class that owns the data

Prerequisites: "Model a Course Roster"

Enforcing a maximum size

public class CourseRoster {
    private String courseName;
    private Integer maxSize;
    private List<Student> enrolledStudents = new List<Student>();

    public CourseRoster(String courseName, Integer maxSize) {
        this.courseName = courseName;
        this.maxSize = maxSize;
    }

    public Boolean enroll(Student student) {
        if (enrolledStudents.size() >= maxSize) {
            System.debug('Roster full — cannot enroll ' + student.getName());
            return false;
        }
        enrolledStudents.add(student);
        return true;
    }
}
  1. public class CourseRoster { — the class.
  2. private String courseName; — unchanged.
  3. private Integer maxSize; — a new field: the enrollment cap.
  4. private List<Student> enrolledStudents = new List<Student>(); — unchanged.
  5. (blank line)
  6. public CourseRoster(String courseName, Integer maxSize) { — the constructor now takes the cap too.
  7. this.courseName = courseName; — sets the name.
  8. this.maxSize = maxSize; — sets the cap.
  9. } — closes the constructor.
  10. (blank line)
  11. public Boolean enroll(Student student) { — now returns a Boolean reporting whether it actually succeeded.
  12. if (enrolledStudents.size() >= maxSize) { — this is Module 6's if-statement pattern doing real business work.
  13. System.debug('Roster full — cannot enroll ' + student.getName()); — a clear reason logged.
  14. return false; — reports failure, so calling code can react instead of blindly assuming every enrollment worked.
  15. } — closes the if.
  16. enrolledStudents.add(student); — only reached if there was room.
  17. return true; — reports success.
  18. } — closes the method.
  19. } — closes the class.

Preventing duplicate enrollment

public Boolean enroll(Student student) {
    for (Student existing : enrolledStudents) {
        if (existing.getStudentId() == student.getStudentId()) {
            System.debug(student.getName() + ' is already enrolled.');
            return false;
        }
    }

    if (enrolledStudents.size() >= maxSize) {
        System.debug('Roster full — cannot enroll ' + student.getName());
        return false;
    }

    enrolledStudents.add(student);
    return true;
}
  1. public Boolean enroll(Student student) { — the method, now with a duplicate check added first.
  2. for (Student existing : enrolledStudents) { — checks every already-enrolled student.
  3. if (existing.getStudentId() == student.getStudentId()) { — matches by id.
  4. System.debug(student.getName() + ' is already enrolled.'); — a clear, specific message.
  5. return false; — rejects the duplicate immediately.
  6. } — closes the if.
  7. } — closes the loop.
  8. (blank line)
  9. if (enrolledStudents.size() >= maxSize) { — the capacity check, run after the duplicate check.
  10. System.debug('Roster full — cannot enroll ' + student.getName()); — a different, generic message.
  11. return false; — rejects for capacity.
  12. } — closes the if.
  13. (blank line)
  14. enrolledStudents.add(student); — only reached if neither check rejected the student.
  15. return true; — reports success.
  16. } — closes the method.

Checking for an existing enrollment before checking capacity means a genuinely duplicate enrollment gets a clear, specific message rather than a generic "roster full" — the order these checks run in actually matters for how helpful the feedback is.

Why these rules live inside CourseRoster

It would be possible to write these checks as separate, standalone code wherever enroll gets called instead — but then every caller would need to remember to repeat them, and any caller that forgot would silently create an invalid roster. Putting the rules inside CourseRoster.enroll() itself (the same encapsulation principle from Module 11) means the rule is enforced everywhere, automatically, with no way to bypass it.

Exercise

Add a getRemainingSeats() method to CourseRoster returning maxSize minus the current enrollment count.

Show hint

return maxSize - enrolledStudents.size();

Salesforce: ○ Not connected Connect
APEX

Execution Results

Run your code to see the result.

Add Business Rules Quiz

1. Why should the maximum-size and duplicate-enrollment rules live inside CourseRoster rather than in every calling piece of code?

Log in to submit the quiz and save your score.

My Notes

Log in to keep private notes on this lesson.

Questions about this lesson

No questions yet — be the first to ask.

Log in to ask a question about this lesson.

Summary

Real rosters have real limits — this lesson adds business rules (a maximum size, no duplicate enrollments) directly inside CourseRoster, where the data they protect actually lives.