【问题标题】:The object-oriented approach to a many-to-many relationship多对多关系的面向对象方法
【发布时间】:2014-09-28 23:23:15
【问题描述】:

我目前正在努力了解如何以面向对象的方式解决此问题。

具有多对多关系,例如学生-科目,其中每个学生都获得特定科目的分数,假设如下:

我希望能够显示给定学生的所有分数。 我想显示给定科目的不同学生的所有分数 我希望能够更改给定科目的任何学生的分数。

我对最后一个有问题,我似乎想不出一种方法来将这些类相互关联,以便在更改时标记保持一致......

这就是我想用伪代码做的事情。假设我们有 3 名学生,每人涉及 3 个科目(共 9 分):

Make a class for Student (String name, int studNumber)

Make a class for Subject (String name, int subNumber)

Make a class for Result(int percentageScore String grade(calculated based on
percentageScore)) 

Then have an array of arrays of Result objects, eg. [1][2] in the array will 
give the score for the student with studNumber 2 in the subject with subNumber 1.   

我觉得这不是面向对象的?在学科和学生的班级设计中应该有某种关系的承认。如果这确实是正确的,有人能指出我正确的方向吗?如何以面向对象的方式做到这一点?

非常感谢。

【问题讨论】:

    标签: java arrays class oop


    【解决方案1】:

    我认为该方法应该与数据库表相同。你应该在这两个之间实现某种“加入类”。那个类应该是单例的,你应该在学生和科目中引用它。该类应该有某种列表或地图,或具有该结构的某种东西,其中将包含属性:学生、主题、标记。这样,您可以通过任何这些属性遍历该集合,这应该可以满足您的需要。这个例子How to make SQL many-to-many same-type relationship table 是针对数据库的,但我认为它应该会给你一些有用的见解。

    【讨论】:

      【解决方案2】:

      为什么要使用如此复杂的类结构。你可以有一个简单的Student class

        class Student{
      
        String stuName;
        long rollNo;
      
        public Student(String stuName, long rollNo){
         this.stuName=stuName;
         this.rollNo=rollNo;
         }
         .
         .
         .
      
        }
      

      还有一个Subject class。每个科目都有特定的学生注册,以及每个学生在该科目中的得分。可以表示为:-

      class Subject{
      
      String subName;
      HashMap<Integer,Student> Result;
      
      public Subject(String subName){
      this.subName=subName;
      Result=new HashMap<Integer,Student>();
      }
      
      //add methods to add students,modify marks, etc
      
      public void addStudent(String name,long roll, int marks){
      
      
      Result.put(marks,new Student(name,roll));
      
      }
      
      public int giveMarksForSubject(long roll){
      
      //iterate Results , and check for student objects to match roll no. return key of matching student
      .
      .
      .
      }
      
        .
        .
      
      }
      

      对于您提到的部分,您想为学生更改特定科目的分数。您可以在 Main 方法的类中通过 String name 搜索 Subject 对象,然后根据 name/rollNo 更改 Student 的标记。您可以在Subject 类中提供方法来实现此类功能。

      【讨论】:

        【解决方案3】:

        学科和成绩的值都是有限的,所以我建议使用枚举:

        public class Example {
        
            public static void main(String[] args) throws IOException {
                Student s1 = new Student("John Doe");
                s1.setGrade(Subject.MATHS, Grade.B);
                s1.setGrade(Subject.PHYSICS, Grade.A);
                s1.setGrade(Subject.ENGLISH, Grade.E);
        
                Student s2 = new Student("Jane Smith");
                s2.setGrade(Subject.MATHS, Grade.C);
                s2.setGrade(Subject.PHYSICS, Grade.C);
                s2.setGrade(Subject.ENGLISH, Grade.A);
        
                // print students and their grades:
                s1.printAllGrades();
                s2.printAllGrades();
        
                // print every subject and its grades:
                for(Subject s : Subject.values()){
                    s.printAllGrades();
                }
            }
        }
        
        enum Subject{
            MATHS, PHYSICS, ENGLISH;
        
            private Map<Student, Grade> grades = new HashMap<Student, Grade>();
        
            public void setGrade(Student student, Grade grade){
                grades.put(student, grade);
            }
        
            public void printAllGrades(){
                System.out.println(this);
                for(Student s : grades.keySet()){
                    System.out.println(s.getName() + " : " + grades.get(s));
                }
            }
        }
        
        enum Grade{ 
            A, B, C, D, E, F
        }
        
        class Student{
        
            private String name;
            private Map<Subject, Grade> grades = new HashMap<Subject, Grade>();
        
            public Student(String name){
                this.name = name;
            }
        
            public String getName(){
                return this.name;
            }
        
            public void setGrade(Subject subject, Grade grade){
                grades.put(subject, grade);
                subject.setGrade(this, grade);
            }
        
            public Grade getGrade(Subject subject){
                return grades.get(subject);
            }
        
            public void printAllGrades(){
                System.out.println("Grades of " + name + ":");
                for(Subject s : grades.keySet()){
                    System.out.println(s + " : " + grades.get(s));
                }
            }
        
        }
        

        使用枚举类型适合列出科目和成绩。它保证只有合适的值可以作为参数传递并且易于扩展 - 如果您愿意,可以将方法添加到枚举。每个学生一个简单的HashMap 就足以保存科目和成绩之间的映射。

        您可能想在enums in java 上阅读更多内容。

        【讨论】:

          【解决方案4】:

          This article 为在您的设计中包含以下结构提供了一个非常有说服力的案例:

          • 学生(包括结果指针数组)
          • 主题(包括结果指针数组)
          • 结果(包含属于关系的所有属性)

          虽然原来的帖子是很久以前的,但希望这对其他人有帮助。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2015-07-11
            • 1970-01-01
            • 2011-03-31
            • 1970-01-01
            • 2010-10-21
            • 2021-08-26
            • 2010-12-07
            相关资源
            最近更新 更多