聽起來像Visitor pattern;來自鏈接的維基百科條目訪客設計模式是一種將算法與其操作的對象結構分離的方式。
編輯基於評論如下,下面是測試框架的完整的例子。
static interface IGradeElementVisitor {
String visit(ExamRecord er);
String visit(StudentData sd);
String visit(SchoolData sd);
}
static interface IGradeElement {
void accept(IGradeElementVisitor igev);
}
static class GradeElementVisitor implements IGradeElementVisitor {
@Override
public String visit(ExamRecord er) {
StringBuilder sb = new StringBuilder();
DateFormat df = new SimpleDateFormat("M/d/yyyy");
sb.append(df.format(er.date)).append(",");
sb.append(er.grade);
return sb.toString();
}
@Override
public String visit(StudentData sd) {
StringBuilder sb = new StringBuilder();
sb.append(sd.name).append(",");
return sb.toString();
}
@Override
public String visit(SchoolData sd) {
StringBuilder sb = new StringBuilder();
for (StudentData student : sd.students) {
for (ExamRecord er : student.records) {
sb.append(sd.name);
sb.append(",");
sb.append(visit(student));
sb.append(visit(er));
sb.append(System.lineSeparator());
}
}
return sb.toString();
}
}
static class ExamRecord implements IGradeElement {
public ExamRecord(Date date, String grade) {
this.date = date;
this.grade = grade;
}
Date date;
String grade;
public void accept(IGradeElementVisitor igev) {
igev.visit(this);
}
}
static class StudentData implements IGradeElement {
public StudentData(String name, List<ExamRecord> records) {
this.name = name;
this.records = records;
}
String name;
List<ExamRecord> records;
public void accept(IGradeElementVisitor igev) {
igev.visit(this);
}
}
static class SchoolData implements IGradeElement {
public SchoolData(String name, List<StudentData> students) {
this.name = name;
this.students = students;
}
String name;
List<StudentData> students;
public void accept(IGradeElementVisitor igev) {
igev.visit(this);
}
}
public static void main(String[] args) {
List<ExamRecord> dans = new ArrayList<>();
dans.add(new ExamRecord(new Date(2001, 2, 2), "A"));
dans.add(new ExamRecord(new Date(2001, 2, 3), "B"));
dans.add(new ExamRecord(new Date(2001, 2, 3), "A"));
dans.add(new ExamRecord(new Date(2001, 2, 5), "C"));
List<ExamRecord> kims = new ArrayList<>();
kims.add(new ExamRecord(new Date(2001, 2, 5), "A"));
kims.add(new ExamRecord(new Date(2001, 2, 5), "B"));
List<ExamRecord> alexs = new ArrayList<>();
alexs.add(new ExamRecord(new Date(2001, 0, 5), "A"));
StudentData dan = new StudentData("dan", dans);
StudentData kim = new StudentData("kim", kims);
StudentData alex = new StudentData("alex", alexs);
List<StudentData> bakers = new ArrayList<>();
bakers.add(dan);
bakers.add(kim);
List<StudentData> thompsons = new ArrayList<>();
thompsons.add(alex);
List<SchoolData> schools = new ArrayList<>();
schools.add(new SchoolData("baker elementary", bakers));
schools.add(new SchoolData("thompson middle school", thompsons));
IGradeElementVisitor visitor = new GradeElementVisitor();
for (SchoolData school : schools) {
System.out.print(visitor.visit(school));
}
}
輸出爲(如需要),
baker elementary,dan,3/2/3901,A
baker elementary,dan,3/3/3901,B
baker elementary,dan,3/3/3901,A
baker elementary,dan,3/5/3901,C
baker elementary,kim,3/5/3901,A
baker elementary,kim,3/5/3901,B
thompson middle school,alex,1/5/3901,A
當然,還有其他的方法來解決這個特別的問題。
對此不確定。我認爲Visitor模式用於處理具有不同對象子類的層次結構,但所有對象都是相同根類的子類,即它們都有一些共同點。我不認爲這個問題的案例適合這種模式。如果你認爲它確實如此,請發表一個在實際案例中將如何使用的例子 - 不僅僅是維基百科頁面中與實際問題關係不明顯的圖表。 – ajb 2014-11-02 00:04:34
@ajb添加了一個示例實現。 – 2014-11-02 01:17:33