Here, in C++ notation, is the full OKI model:
class CourseManagementManager { // single instance class CanonicalCourse createCanonicalCourse(String title, String number, String description, Type courseType); CourseGroup createCourseGroup(Type courseGroupType); GradeRecord createGradeRecord(Agent studet, Id courseOfferingId, Type gradeType, Serializable grade); Term createTerm(Type termType, ScheduleItemIterator schedule); void deletCanonicalCourse(Id canonicalCourseId); void deletCourseGroup(Id courseGroupId); void deleteGradeRecord(Id gradeRecordId); void deleteTerm(Id termId); CanonicalCourse getCanonicalCourse(); CanonicalCourseIterator getCanonicalCourses(); CanonicalCourseIterator getCanonicalCourses(Type courseType); CourseGroup getCourseGroup(); CourseGroupIterator getCourseGroups(); CourseGroupIterator getCourseGroups(Type courseGroupType); TypeIterator getCourseGroupTypes(); CourseOffering getCourseOffering(Id courseOfferingId); CourseSection getCourseSection(Id courseSectionId); TypeIterator getCourseTypes(); GradeRecordIterator getGradeRecords(Agent student, Id courseOfferingId, Type gradeType); TypeIterator getGradeTypes(); TypeIterator getOfferingTypes(); TypeIterator getSectionTypes(); TypeIterator getStatusTypes(); TypeIterator getStudentTypes(); Term getTerm(Id termId); TermIterator getTerms(); TypeIterator getTermTypes(); // implied attributes set<CanonicalCourse> canonicalCourses; set<CourseGroup> courseGroups; set<Type> courseGroupTypes; set<Type> courseTypes; set<Type> gradeTypes; set<Type> offeringTypes; set<Type> sectionTypes; set<Type> statusTypes; set<Type> studentTypes; set<Term> terms; set<Type> termTypes; } theCourseManagementManager; class CanonicalCourse { void addEquivalentCourse(CanonicalCourse canonicalCourse); void addTopic(Strig topic); CanonicalCourse createCanonicalCourse(String title, String number, String description, Type courseType); CourseOffering createCourseOffering(String title, String number, String description, Term term, Type offeringType); void deleteCanonicalCourse(Id canonicalCourseId); void deleteCourseOffering(Id courseOfferingId); CanonicalCourseIterator getCanonicalCourses(); CanonicalCourseIterator getCanonicalCourses(Type courseType); CanonicalOfferingIterator getCourseOfferings(); CanonicalOfferingIterator getCourseOfferings(Type offeringType); Type getCourseType(); float getCredits() String getDescription(); CanonicalCourseIterator getEquivalentCourses(); Id getId(); String getNumber(); String getTitle(); StringIterator getTopics(); void removeEquivalentCourse(Id canonicalCourseId); void removeTopic(String topic); void updateCredits(float credits); void updateDescription(String description); void updateNumber(String number); void updateTitle(String title); // implied attributes set<CanonicalCourse> canonicalCourses; set<CourseOffering> courseOfferings; set<CanonicalCourse>& equivalentCourses; // could be a CourseGroup set<String> topics; float credits String description; String number; String title; // also needed set<CanonicalCourse> prerequisites; // or course gp. Omitted by OKI }; class CourseOffering { CourseSection createCourseSection(String title, String number, String description, Type sectionType); void deleteCourseSection(Id courseSectionId); Id getAssetId(); CanonicalCourse getCanonicalCourse(); CourseOfferingIterator getCourseSections(); CourseOfferingIterator getCourseSections(Type sectionType); Type getStatus(); String getDescription(); Type getGradingOptionType(); Id getId(); String getNumber(); Type getOfferingType(); Term getTerm(); String getTitle(); void updateAssetId(Id assetId); void updateStatus(Type courseStatusType); void updateDescription(string description); void updateGradeType(Type gradingOptionType); void updateNumber(String number); void updateTitle(String title); // implied attributes Id assetId; const CanonicalCourse canonicalCourse; // shouldn't this be a set of eqvs set<CourseSection> courseSections; Type status; String description; Type gradingOptionType; String number; const Term term; String title; }; class CourseSection { void addStudent(Agent student); Id getAssetId(); String getDescription(); Id getId(); Serializable getLocation(); String getNumber(); AgentIterator getRoster(); ScheduleItemIterator getSchedule(); Type getSectionType(); String getTitle(); CourseOfferingIterator getCourseOfferings(); void removeStudent(Id studentId); void updateAsset(Id assetId); void updateDescription(String description); void updateLocation(Serializable location); void updateNumber(String number); void updateSchedule(ScheduleItem[] scheduleItems); void updateTitle(String title); // implied attributes Type status; // open, closed, etc. Omitted by OKI. Id assetId; // rooms, labs, etc. Should be set String description; Serializable location; String number; set<Agent> roster; set<ScheduleItem> schedule; String title; set<CourseOffering> courseOfferings; // also need enrollment limits etc. }; class Term { Id getId(); ScheduleItemIterator getSchedule(); Type getTermType(); // implied attributes set<ScheduleItem> schedule; }; class GradeRecord { Agent getAgent(); Id getCourseOffering(); Serializable getGrade(); Id getId(); Type getType(); void updateGrade(Serializable grade); // implied attributes const Agent& agent; const CourseOffering& courseOffering; Serializable grade; }; class CourseGroup { void addCourseToGroup(Id canonicalCourseId); CanonicalCourseIterator getCourses(); Id getId(); Type getType(); void removeCourseFromGroup(Id canonicalCourseId); // implied attributes set<CanonicalCourse> courses; // a set of references. }; // Grading class GradingManager { Assignment createAssignment(String name, String description, Id courseSectionId, Id gradableObjectId, Type gradeType, ScoringDefinition scoringDefinition, GradeScale gradeScale); GradeRecord createGradeRecord(Id assignmentId, Agent agent, Serializable gradeValue, Type gradeRecordType); void deleteAssignment(Id assignmentId); void deleteGradeRecord(Id gradeRecordId); AssignmentIterator getAssignments(Id courseSectionId, Id gradableObjectId); GradeRecordIterator getGradeRecords(Id courseSectionId, Id assignmentId, Agent agent, Type grdeRecordType); TypeIterator getGradeRecordTypes(); TypeIterator getGradeScales(); TypeIterator getGradeTypes(); TypeIterator getScoringDefinitions(); // implied attributes set<Assignment> assignments; set<GradeRecord> gradeRecords; set<Type> gradeRecordTypes; set<Type> gradeScales; set<Type> gradeTypes; set<Type> scoringDefinitions; }; class Assignment { Id getCourseSectionId(); String getDescription(); String getDisplayName(); Id getGradableObject(); Type getGradeScale(); Type getGradeType(); Id getId(); Type getScoringDefinition(); void updateDescription(String description); void updateDisplayName(String displayName); // implied attributes const CourseSection& courseSectionId; String description; String displayName; const GradableObject& gradableObject; // what's assigned to be graded const Type gradeScale; const Type gradeType; const Type scoringDefinition; }; class GradeRecord { Agent getAgent(); Id getAssignmentId(); Serializable getGradeValue(); Type getGradeType(); Agent getModifiedBy(); Calendar getModifiedDate(); void updateGradeValue(Serializable gradeValue); // implied attributes const Agent& agent; const Assignment& assignmentId; Serializable gradeValue; const Agent& modifiedBy; const Calendar modifiedDate; const Type gradeType; }; // Assessments class AssessmentManager{ Assessment createAssessment(String name, String description, Type AssessmentType); AssessmentPublished createAssementPublished(Assessment assessment); Evaluation createEvaluation(AssessmentTaken assessmentTaken, Type evaluationType, Agent agent); Evaluation createEvaluation(ItemTaken itemTaken, Type evaluationType, Agent agent); Evaluation createEvaluation(SectionTaken sectionTaken, Type evaluationType, Agent agent); Item createItem(String name, String description, Type itemType); Section createSection(String name, String description, Type sectionType); void deleteAssessment(Id assessmentId); void deleteAssessmenPublished(Id assessmentPublishedId); void deleteEvaluation(Id evaluationId); void deleteItem(Id itemId); void deleteSection(Id sectionId); Assessment getAssessment(Id assessmentId); AssessmentPublished getAssessmentPublished(Id assessmentPublishedId); AssessmentIterator getAssessments(); AssessmentIterator getAssessments(Type assessmentType); AssessmentPublishedIterator getAssessmentsPublished(); AssessmentTakenIterator getAssessmentsTaken(); TypeIterator getAssessmentTypes(); TypeIterator getEvaluationTypes(); Item getItem(Id itemId); ItemIterator getItems(); ItemIterator getItems(Type itemType); TypeIterator getItemTypes(); Section getSection(Id sectionId); SectionIterator getSections(); SectionIterator getSections(Type sectionType); TypeIterator getSectionTypes(); // implied attributes set<Assessment> assessments; set<AssessmentPublished> assessmentsPublished; set<AssessmentTaken> assessmentsTaken; set<Evaluation> evaluations; set<Item> items; set<Section> sections; set<Type> assessmentTypes; set<Type> evaluationTypes; set<Type> sectionTypes; set<Type> itemTypes; }; class Assessment { void addSection(Section section); Type getAssessmentType(); Serializable getData(); String getDescription(); String getDisplayName(); Id getId(); SectionIterator getSections(); String getTopic(); void orderSections(Section[] sections); void removeSection(Id sectionId); void updateData(Serializable data); void updateDescription(String description); void updateDisplayName(String displayName); void updateTopic(String topic); // implied attributes. Must also order sections. set<Section> section; Serializable data; String description; String displayName; String topic; }; class AssessmentPublished { AssessmentTaken createAssessmentTaken(Agent agent); void deleteAssessmentTaken(Id assessmentTakenId); Assessment getAssessment(); AssessmentTakenIterator getAssessmentsTaken(); Id getCourseSection(); Serializable getData(); Calendar getDate(); String getDescription(); String getDisplayName(); Id getGradingAssignment(); Id getId(); void updateCourseSection(Id id); void updateData(Serializable data); void updateDescriptiion(String description); void updateDisplayName(String displayName); void updateGradingAssignment(Id id); // implied attributes const Assessment assessment; set<AssessmentTaken> assessmentsTaken; CourseSection& courseSection; Serializable data; const Calendar date; String description; String displayName; Id gradingAssignment; }; class AssessmentTaken { Evaluation createEvaluation(Type evaluationType); SectionTaken createSectionTaken(Section section); void deleteSectionTaken(Id sectionTakenId); Agent getAgent(); AssessmentPublished getAssessmentPublished(); Serializable getData(); Calendar getDate(); EvaluationIterator getEvaluations(); EvaluationIterator getEvaluations(Type evaluationType); SectionTakenIterator getSectionsTake(); void deleteEvaluation(Id evaluationId); void updateData(Serializable data); // implied attributes. set<Evaluation> evaluations; // summative from per-sections evals set<SectionTaken> sectionsTaken; const AssessmentPublished& assessmentPublished; const Agent& agent; // student Serializable data; const Calendar date }; class Evaluation { Serializable getData(); Id getId(); Agent getModifiedBy(); Calendar getModifiedDate(); Id getObjectTaken(); Type getType(); void updateData(Serializable data); // implied attrubutes Serializable data; const Agent& modifiedBy; // these should be expanded to lists const Calendar modifiedDate; const ObjectTaken& objectTaken; // the item, section, or assessment // being evaluated }; class Item { Serializable getData(); String getDescription(); String getDisplayName(); Id getId(); Type getItemType(); void updateData(Serializable data); void updateDescription(String description); void updateDisplayName(String displayName); // implied attributes Serializable data; // answer, rubric, etc. String description; String displayName; }; class ItemTaken { Evaluation createEvaluation(Type evaluationType); void deleteEvaluation(Id evaluationId); Serializable getData(); EvaluationIterator getEvaluations(); EvaluationIterator getEvaluations(Type evauationType); Item getItem(); SectionTaken getSectionTaken(); void updateData(Serializable data); // implied attributes. So, where does the student's work go? Data? Serializable data; set<Evaluation> evaluations; const Item& item; // master copy of this item const SectionTaken& sectionTaken; }; class Section { void addItem(Item item); void addSection(Section section); // subsections Serializable getData(); String getDescription(); String getDisplayName(); Id getId(); ItemIterator getItems(); SectionIterator getSections(); // subsections Type getSectionType(); void orderItems(Item[] items); void orderSections(Section[] sections); void removeItem(Id itemId); void removeSection(Id sectionId); void updateData(Serializable data); void updateDescription(String description); void updateDisplayName(Striing displayName); // implied attributes Also need ordering of items and subsections. set<Item> items; // questions/problems set<Section> sections; // subsections Serializable data; // whatever String description; String displayName; }; class SectionTaken { Evaluation createEvaluation(Type evaluationType); void deleteEvaluation(Id evaluationId); AssessmentTaken getAssessmentTaken(); Serializable getData(); EvaluationIterator getEvaluations(); EvaluationIterator getEvaluations(Type evaluationType); ItemIterator getItemsTaken(); Section getSection(); void updateData(Serializable data); // implied attributes const Section& section; // master copy of this section set<Evaluation> evaluations; // from evals of items & subsections taken Serializable data; // ?? grading formulae? set<ItemTaken> itemsTaken; set<SectionTaken> sectionsTaken; // subsections taken const AssessmentTaken& assessmentTaken; // ? parent section or assessment };