有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java OOP类职责

我正在开发一个爱好项目来正确理解封装、类可以负责什么以及规则。我在另一个forum中请求代码审查和帮助,但我不同意给出的方法

我有以下要求:

  • 国际学生需要文件才能完成注册过程,而国内学生则不需要

学生状态界面:

public interface StudentStatus {
    Collection<String> retrieveDocuments();
    StudentType retrieveStatus();
}

 public final class Domestic implements StudentStatus {

       private final StudentType type;
       private final Collection<String> documents;

       public Domestic() {
           this.type = StudentType.Domestic;
           this.documents = Collections.emptyList();
       }

       @Override
       public Collection<String> retrieveDocuments() {
           return this.documents;
       }

       @Override
       public StudentType retrieveStatus() {
           return type;
       }
   }

public final class International implements StudentStatus {

   private final StudentType type;
   private Collection<String> documents;


   public International(Collection<String> documents) {

       this.type = StudentType.International;
       this.documents = Collections.unmodifiableCollection(documents);
   }

   @Override
   public Collection<String> retrieveDocuments() {
       return Collections.unmodifiableCollection(documents);
   }

   @Override
   public StudentType retrieveStatus() {
      return type;
   }
}

学生班:

public final class Student {

     //left out constructor and getters for other attributes. 

     public Collection<String> retrieveDocuments() {
           return status.retrieveDocuments();
     }

     public StudentType retrieveStatus() {
          return status.retrieveStatus();
     }

     public boolean isVerified(StudentType type) {
         return this.retrieveStatus() == type;
     }
}

大学课堂:

public class University {

    private final Map<Student,Collection<String>> registeredStudents;
    private final StudentType type;

    public University()
    {
        registeredStudents = new HashMap<Student,Collection<String>>();
        type = StudentType.International;
    }

    public void add(Student student){
        if (student.isVerified(type)){
            registeredStudents.put(student, student.retrieveDocuments());
        }else {
            //throw an exception or handle error accordingly 
        }
    }
}

在我继续之前,我明白这是一个过于简化的申请过程。在现实世界中,在学生注册之前,还有很多事情要做。学生可能必须通过入学考试,并在注册开始前付款。此外,在现实环境中,这些信息可能会存储在校园员工可以访问的数据库中

在另一个论坛上,对话讨论了发布的信息和方法

  • 有一个规则类,它接受Student对象并验证它 事实上是国际性的,并且有文件

我的问题是,你仍然需要问学生他/她的状态,或者是retriveStatus()或者isVerified(),我真的不知道怎么做

  • 将要添加到地图中的学生和文件集合分别传递给学生

在现实世界中,大学按照上述规定制定规则,其责任是检查国际学生是否有文件

当我向add(Student student)提出上述方法时,他们说这不是一个好主意,因为规则可能会改变,你必须改变学生班级和大学班级

然而,在现实世界中,学生很清楚自己的身份,以及他/她是否是国内/国际学生,是否拥有可以提供给学校的文件

鉴于上述方法,以这种方式编写add方法是个好主意吗?有比add方法更好的方法吗

tl;dr-如果学生必须遵守大学设定的规则,那么学生对象将如何与大学通信以获取数据,以便大学能够确保学生对象遵守规则而不破坏封装


共 (2) 个答案

  1. # 1 楼答案

    你说:

    In the real world, the University set the rule as stated above and it's responsibility is to check if International students have documentation.

    这意味着验证责任在于大学(每个大学可能不同),而不是学生。学生所能做的就是提供必要的信息供大学核实

    add方法应该从retrieveDocuments获取文档,并运行其规则,以确定是否允许接受is student

  2. # 2 楼答案

    上一篇帖子中的对话可能会引导你朝着一个总体上良好的方向前进。最适用的原则是打开/关闭原则https://en.wikipedia.org/wiki/Open/closed_principle

    不要把自己设置为必须在一个你知道将成为频繁变化向量的领域不断修改一个特定类或一组类(至少在OO世界中是这样)。这一原则同样适用于函数世界,但您的示例使用的是OOPL

    小型手工构建的规则引擎是一个很好的解决方案。尤其是如果你知道规则是在相当固定的输入上流动的——比如大学和学生。国际学生所需的文档是该体系结构中的一个规则类——只有当规则本身发生变化时才需要更改。新规则,这将经常发生=添加新类,而不是修改现有类

    有时,你不知道变化的方向,更难做出决定,但如果这是显而易见的,不要构建一个系统,因为已知的变化方向,你必须不断地违反开放/关闭

    有不同的方法来实现小规则引擎。一个选项(这是蹩脚的伪代码,占用的空间更少)

    interface RegistrationRule
     boolean isRegistrationValid(Student student)  //might need university too for some rules.
    
    class DocumentsNeededForInternationalStudents implements RegistrationRule
     boolean isRegistrationValid(Student student) 
     // return student.status is international and student has documents, or student status is domestic 
    // (this rule passes through as valid any domestic students).
    
    class RegistrationRules 
    // (holds all the rules you will use - kind of a factory)
    constructor -> add to static list of rules an instance of all your rules
    boolean runRulesForStudent(Student)
      //iterate through all rules, call isRegistrationValid, short circuit and return false if one of them false
    
    
    class University
    addStudent(Student student)
      if (RegistrationRules.runRules(student).... else
    

    这只是将其组合在一起的一种方法,但你可以看到它并不是很多代码。您有一个接口、每个规则的一个实现类,以及一个为您应用每个规则的小规则引擎类。New rule=New class,在规则引擎中修改构造函数以添加该类的实例,完成

    当规则中需要的属性和行为非常多样化,并且不集中在同一个小类集中时,这种模式开始有点困难