...
Method Factoring
Kicking The Can
Here’s an example of an attempt to replace a GradeSystem for a Course using the kick-the-can method:
Code Block |
---|
public class CourseLookupSession
implements org.osid.course.CourseLookupSession {
private org.osid.course.CourseLookupSession courseLookupSession;
private org.osid.grading.GradeSystemLookupSession gradeSystemLookupSession;
private org.osid.relationship.RelationshipLookupSession relationshipLookupSession;
@OSID
public org.osid.course.CourseList getCourses()
throws org.osid.OperationFailedException,
org.osid.PermissionDeniedException {
return (processCourses(this.courseLookupSession.getCourses()));
}
private org.osid.course.CourseList processCourses(org.osid.course.CourseList courses)
throws org.osid.OperationFailedException,
org.osid.PermissionDeniedException {
MutableCourseList ret = new MutableCourseList();
while (courses.hasNext()) {
ret.add(processCourse(courses.getNextCourse()));
}
ret.done();
return (ret);
}
private org.osid.course.Course processCourse(org.osid.course.Course course)
throws org.osid.OperationFailedException,
org.osid.PermissionDeniedException {
if (course.isGraded()) {
return (processGradingOptions(course));
} else {
return (course);
}
}
private org.osid.course.Course processGradingOptions(org.osid.course.Courss course)
throws org.osid.OperationFailedException,
org.osid.PermissionDeniedException {
Collection<org.osid.grading.GradeSystem> mappedGradeSystems = new ArrayList<>();
try (org.osid.grading.GradeSystemList gradeSystems = course.getGradingOptions()) {
while (ids.hasNext()) {
org.osid.grading.GradeSystem gradeSystem = gradeSystems.getNextGradeSystem();
try {
mappedGradeSystems.add(getNewGradingOption(gradeSystem.getId()));
} catch (org.osid.NotFoundException nfe) {
mappedGradeSystems.add(gradeSystem);
}
}
}
return (mapCourseToNewGradeSystems(course, mappedGradeSystems);
}
private org.osid.grading.GradeSystem getNewGradingOption(org.osid.id.Id gradeSystemid)
throws org.osid.NotFoundException,
org.osid.OperationFailedException,
org.osid.PermissionDeniedException {
try (org.osid.relationship.RelationshipList mappings = this.relationLookupSession.getRelationshipsForSource(gradeSystemId)) {
if (mappings.hasNext()) {
return (this.gradeSystemLookupSession.getGradeSystem(mappings.getNextRelationship().getDestinationId()));
} else {
throw new org.osid.NotFoundException("cannot map " + gradeSystemId);
}
}
}
private org.osid.course.Course mapCourseToNewGradeSystems(course, mappedGradeSystems)
throws org.osid.OperationFailedException,
org.osid.PermissionDeniedException {
return (new CourseWrapper(course, mappedGradeSystems));
} |
The above code pushes the logic of each loop into a separate method. The resulting flow describes a procedure. Some of the symptoms include:
a trail of private methods strung together
method names with the word process in them
lack of clarity over which method is responsible for what job
the inability to reuse any part of the trail other than the head
one utility for the list and another for an individual element on the list
needing to declare the same exceptions at each point and the resulting exceptions actually thrown could come from anywhere along the trail.
This factoring approach worked fine in C & Fortran.
See Also
...