COMP433 · Software Engineering · Chapter 4 · Tutorial

From requirements to a class and sequence diagram

Tutorial worksheet. Work the tasks below on paper, in the notation taught in this course (Adel / Sommerville). The use case and activity diagrams are given; you produce the class diagram and the sequence diagram. Worked solutions are provided in Section 4 as collapsible panels - attempt each task first, then expand to check.

1. The problem

A university needs a system for course registration. A student may register for several course offerings in a semester, up to a credit limit. A course (for example COMP433) is given as one or more offerings (sections) per semester; each offering is taught by one instructor, has a time and room, and a maximum capacity. A student may register for an offering only if they have passed the course's prerequisites and the offering is not full. The system records each registration with a date and a status; at the end of the semester the instructor records a grade for each registration. A student may drop an offering before the deadline. A registrar manages the offerings.

2. Given to you

Start from these behavioural models; your work begins at the structure.

Given 1
Use case diagram for the Course Registration System.
Course Registration SystemStudentRegistrarInstructorRegister forofferingCheckprerequisitesRefuseregistrationDrop offeringView scheduleRecord gradeManage offerings«include»«extend»
Three actors. Register for offering «include»s Check prerequisites (always part of registering); Refuse registration «extend»s Register for offering (only when a prerequisite is unmet or the offering is full).
Given 2
Activity diagram for “Register for offering”.
Select offeringprerequisitesmet?[yes]spaceavailable?[yes]Create registrationConfirm to studentRefuse:prerequisites unmetRefuse:offering full[no][no]
Two decisions, each with a guarded refuse branch; the happy path creates the registration and confirms. The decisions reappear as an alt in the sequence diagram.

3. Your tasks

  1. Noun-verb analysis: list candidate classes, then decide keep / reject / debatable with a one-line reason for each.
  2. Classes: draw the classes with their attributes and key operations.
  3. Associations: add associations with multiplicity at each end, plus any generalisation, aggregation/composition, and the association class. This is your class diagram.
  4. Sequence diagram for Register for offering: the normal (happy) path as an instance, then show where an alt handles “prerequisite not met / offering full”. Remember: actors get no activation bar.

4. Worked solutions

Try each task on paper first, then expand the matching panel. There is rarely one “correct” diagram - what matters is that the classes, multiplicities and message order are defensible against the requirements. Hover over the highlighted parts of each solution diagram for a note on what they are and where they come from.
Solution - Task 1: noun-verb analysis

Underline the nouns and verbs in the problem, then sort the nouns into classes, attributes, and things to discard. The verbs become candidate operations.

Candidate (noun)DecisionReason
StudentKeep (class)Has identity, attributes (credit limit) and behaviour (registers, drops).
CourseKeep (class)A catalogue entry (e.g. COMP433) with code, title, credits; distinct from its offerings.
Offering / sectionKeep (class)A specific delivery of a course in a semester, with time, room, capacity. The thing a student actually registers for.
InstructorKeep (class)Teaches offerings and records grades.
RegistrarKeep (class)Manages offerings; a distinct role/actor with behaviour.
RegistrationKeep (association class)It only exists for a (student, offering) pair and carries date, status and grade - the classic association class.
Semester, time, room, capacity, credit limit, date, status, gradeReject; these are attributesSimple values that belong inside a class, not objects with their own identity.
COMP433RejectAn instance of Course, not a class.
University, systemRejectThe context / the system boundary itself, not a domain class.
PrerequisiteDebatableBest modelled as a reflexive association on Course (Course–Course), not a class. Could be a class only if it carried its own data.
GradeDebatableHere an attribute of Registration; would become a class only if grade history/scale needed its own behaviour.

Verbs → candidate operations: register (for offering), check prerequisites, refuse registration, create registration, confirm, drop (offering), record (grade), manage offerings, view schedule.

Solution - Task 2: classes with attributes and operations

A defensible set of classes. Visibility is shown with + public, - private; types follow Sommerville/Adel style.

ClassAttributesKey operations
Studentid, name, creditLimit : intregister(o), drop(o), viewSchedule()
Coursecode, title, credits : int-
OfferingofferingId, semester, time, room, capacity : intisFull() : bool, addRegistration(r)
Instructorid, namerecordGrade(r, g)
Registrarid, namemanageOfferings()
Registration (assoc. class)date : Date, status, gradesetGrade(g), drop()

Student, Instructor and Registrar share id/name, so an abstract Person superclass generalising the three is a reasonable refinement (the generalisation asked for in Task 3). It is optional; show it only if it earns its place.

Solution - Task 3: the class diagram

The associations, with multiplicity at each end:

  • Student - Offering (registers for), 0..* to 0..*, with Registration as the association class (date, status, grade live on the link, not on Student or Offering).
  • Course ◆- Offering (offered as), composition, 1 to 1..*: an offering cannot exist without its course.
  • Instructor - Offering (teaches), 1 to 0..*.
  • Registrar - Offering (manages), 1 to 0..*.
  • Course - Course (prerequisite), a reflexive association 0..* to 0..*.
Solution 3
Class diagram for the Course Registration System.
Student id, name creditLimit : int register(o), drop(o) viewSchedule() Course code, title credits : int   prerequisite 0..* / 0..* Offering offeringId, semester time, room capacity : int isFull() : bool addRegistration(r) Instructor id, name recordGrade(r, g) Registrar id, name manageOfferings() Registration association class date : Date status, grade setGrade(g), drop() 0..* 0..* registers for 1 1..* offered as 1 0..* teaches 1 0..* manages
The two hard decisions: Registration is an association class on Student–Offering (a registration belongs to the pairing, not to either side), and Course◆–Offering is composition (no course, no offering). Prerequisite is a reflexive association on Course. An abstract Person over Student/Instructor/Registrar is an acceptable extra generalisation.
Why this model is defensible. The exercise has no single "right" picture; what matters is that each decision can be argued from the requirements.
  • Registration is an association class, not an attribute and not a plain class. A registration's date, status and grade describe one (student, offering) pairing. They cannot sit on Student (a student has many registrations) or on Offering (an offering has many), so they belong to the link itself. That is the textbook signal for an association class.
  • Course◆–Offering is composition, not aggregation or a plain association. An offering has no independent existence: it is always an offering of a course, and if the course is withdrawn its offerings go with it. That exclusive, lifecycle ownership is exactly what the filled diamond states; a hollow (aggregation) diamond would wrongly claim the offering can outlive its course.
  • The multiplicities are read off the requirements. Student 0..*0..* Offering: a student registers for many offerings up to the credit limit, and an offering enrols many students up to its capacity (zero at each end, because a new student or a freshly created offering may have none yet). Course 11..* Offering: every offering belongs to exactly one course, and a course is given as one or more offerings. Instructor 10..* and Registrar 10..* Offering read the same way.
  • Prerequisite is a reflexive association on Course (0..* at both ends): a course may require several others and may itself be required by several. Modelling it as a class would add nothing, because it carries no data of its own.
  • The Person generalisation is deliberately optional. Student, Instructor and Registrar share only id and name; if that is the whole overlap, keeping them separate is fine. Introduce an abstract Person superclass only when it removes real duplication of attributes or behaviour, not for its own sake.
  • It is consistent with the behaviour. Every operation in the boxes is exercised by a use case: register()/drop() by the student, isFull() and addRegistration() during registration, recordGrade() by the instructor, manageOfferings() by the registrar. An operation that no scenario calls, or a message with no operation to land on, signals a gap between the structure and the behaviour.
Solution - Task 4: the sequence diagram

One scenario of Register for offering. The two decisions from the activity diagram (prerequisites met? space available?) collapse into one alt with a guard. The Student is an actor, so it has no activation bar; the «create» message brings the Registration object to life at the point it is created.

Solution 4
Sequence diagram: “Register for offering” with an alt for refusal.
: Student : RegistrationUI offering : Offering r : Registration 1: register(offering) 2: checkPrerequisites(student) prerequisitesMet 3: isFull() false alt [prerequisites met and space available] 4: «create» new(student, offering, today) 5: addRegistration(r) ok 6: confirm() [else] refuse(reason)
Solid arrows are synchronous calls; dashed open-headed arrows are returns. The Offering answers checkPrerequisites and isFull. In the [prerequisites met and space available] branch the UI creates the Registration with a «create» message, registers it with the Offering through addRegistration(r) (whose ok return hands control back to the UI), then replies confirm() to the Student; in the [else] branch it replies refuse(reason). The Student is an actor, so it carries no activation bar.
How the interaction follows from the requirements.
  • One use case, one scenario. The diagram realises Register for offering for a single student and offering - the normal path - with the two failure paths folded into a single alt. It deliberately leaves dropping, grading and browsing to their own diagrams; trying to show every path in one picture is the most common sequence-diagram mistake.
  • The checks mirror the activity diagram. checkPrerequisites and isFull are the two decisions of the given activity diagram, in the same order, and the guard [prerequisites met and space available] is precisely the conjunction of their two "yes" branches. The behavioural models stay in step.
  • Every message lands on an operation in the class diagram. isFull() is declared on Offering; the controller only calls operations that exist. A message with no home would mean the class model is missing an operation - the sequence diagram is a live check on the structure.
  • The Registration is created, then the UI regains control. The «create» message instantiates r : Registration, the association-class object from the class diagram; its box appears at the point of creation. The UI then calls addRegistration(r) on the Offering, and the ok return from that call is what hands control back to the UI, which can then reply confirm() to the Student. The Registration object receives no further message in this scenario, so it stays idle and carries no activation bar, the same situation as the Loan in the companion's Figure 7c.
  • The actor has no activation bar. The Student is external to the system; we model only the execution of the system's own objects, so only RegistrationUI and Offering are barred.