Assignment 7: Visitors and Circular Data
Goals: To practice using the visitor pattern and designing cyclic data.
Instructions
As always, be very careful with your naming conventions. You should not use mutation on the first problem, but the second problem does require mutation.
Due Date: Thursday March 13th at 9:00pm
Problem 1: Understanding Visitors
Getting started
Start a new project, and copy into it the following definitions of IList<T> and its supporting classes.
//represents a generic list interface IList<T> { } //represents an empty generic list class MtList<T> implements IList<T> { } //represents a generic non-empty list class ConsList<T> implements IList<T> { T first; IList<T> rest; ConsList(T first, IList<T> rest) { this.first = first; this.rest = rest; } }
7.1 Visitors for lists
In the following exercises, if you need to use any function objects, define them using the ones in Java’s functional interfaces.
Make sure to test the visitors that you design on lists of at least two different types. You may omit testing of the simple function objects.
Define an IListVisitor interface. How many type parameters will it need? (Hint: how many type parameters did the IShapeVisitor from class need, compared to how many type parameters IShape itself needed?) What methods will the visitor need? (Hint: what methods did the IShapeVisitor need, and how did that relate to the classes we had that implemented IShape?) Name all your methods visit(...) —
this is another example of overloading. Define a method ?????? accept(IListVisitor<??????> v) on IList<T>, and implement it on the classes implementing IList<T>. Fill in the question marks with whatever type parameter(s?) are needed.
Design a MapVisitor for lists. This visitor should behave like the map method that we designed in class.
Design a FoldRVisitor for lists that behaves like the foldr method we designed in class.
Design an AppendVisitor for lists which appends a given list to the end of this list (this list is the one that is being visited).
7.2 Visitors for ancestor trees
In the same project, copy the IAT interface and related classes from below into your project.
//represents an ancester tree interface IAT { } //represents an unknown ancestor tree class Unknown implements IAT { Unknown() { } } //represents a person in an ancester tree class Person implements IAT { String name; int yob; IAT parent1; IAT parent2; Person(String name, int yob, IAT parent1, IAT parent2) { this.name = name; this.yob = yob; this.parent1 = parent1; this.parent2 = parent2; } }
Design a visitor for IATs: define an IATVisitor interface. Name all your methods in IATVisitor visit(...) Add an accept method to IAT, and implement it for the relevant classes.
Design an IATVisitor called NamesVisitor that produces an IList<String> of the names of the people in an IAT. (Hint: you will probably want to use the AppendVisitor you designed earlier!)
Problem 2: The Registrar’s Office
The registrar’s office maintains a great deal of information about classes, instructors, and students. Your task in this problem is to model that data, and implement a few methods on it. We deliberately do not give you the class diagram for this problem: from the description below, you should properly design whatever classes you think are relevant. Please use generic lists (i.e. IList<T>) for this problem.
7.1 Data constraints
A Course consists of a name (a String), an Instructor named prof, and a list of Students named students. No Course can be constructed without an Instructor available to teach it. Hint: Do you think that you should provide a list when constructing a Course? Why or why not?
An Instructor has a name and a list of Courses named courses he/she/they teaches. Instructors are initially constructed without any Courses to teach.
A Student has a name, an id number (an int), and a list of Courses they are taking. Students are initially constructed without taking any Courses.
It should always be the case that any Student who is enrolled in a Course should appear in the list of Students for that Course, and the Course should likewise appear in the Student’s list of Courses.
It should always be the case that the Instructor for any Course should have that Course appear in the Instructor’s list of Courses.
7.2 Methods and examples to design
Design a method void enroll(Course c) that enrolls a Student in the given Course. Design any helper methods as appropriate.
Design a method boolean classmates(Student c) that determines whether the given Student is in any of the same classes as this Student.
Design a method boolean dejavu(Student c) that determines whether the given Student is in more than one of this Instructor’s Courses.
Construct example data consisting of at least five Students, at least four Courses and at least two Instructors. Test all your methods thoroughly.