2014-11-01 59 views
2

我是從一個組成層次的方式,「變平」出來的數據導出數據需要的數據。因此,例如,我有4個班,每一個有下一個集合在層次結構下:模式的操作,從一個完整的組成層次

SchoolData - > StudentData - > ExamRecord

我想將其導出爲扁平的方式,使得一些的

baker elementary,dan,3/2/2001,A 
baker elementary,dan,3/3/2001,B 
baker elementary,dan,3/3/2001,A 
baker elementary,dan,3/5/2001,C 
baker elementary,kim,3/5/2001,A 
baker elementary,kim,3/5/2001,B 
thompson middle school,alex,1/5/2001,A 

其中的日期和檔次是examrecord成員方面,學生的姓名是StudentData的字符串成員,校名是SchoolData的字符串成員。

很顯然,我可以實現相應的getter和所有的數據拉起頂級函數調用打印出的一切,但我不知道是否有一個更優雅的方式來做到這一點。

我使用的是C++,但語言不應該管那麼多了。

回答

3

聽起來像Visitor pattern;來自鏈接的維基百科條目訪客設計模式是一種將算法與其操作的對象結構分離的方式。

Java example from Wikipedia article

編輯基於評論如下,下面是測試框架的完整的例子。

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 

當然,還有其他的方法來解決這個特別的問題。

+0

對此不確定。我認爲Visitor模式用於處理具有不同對象子類的層次結構,但所有對象都是相同根類的子類,即它們都有一些共同點。我不認爲這個問題的案例適合這種模式。如果你認爲它確實如此,請發表一個在實際案例中將如何使用的例子 - 不僅僅是維基百科頁面中與實際問題關係不明顯的圖表。 – ajb 2014-11-02 00:04:34

+0

@ajb添加了一個示例實現。 – 2014-11-02 01:17:33

相關問題