OOP类责任 [英] OOP Class Responsibility

查看:168
本文介绍了OOP类责任的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个业余爱好项目,以正确理解封装,可以负责的类和规则。我要求在另一个论坛中进行代码审查和帮助,但我不知道同意给出的方法。

I'm developing a hobby project to properly understand encapsulation, what classes can be responsible for, and rules. I asked for a code review and assistance in another forum, but I don't agree with the approach given.

我有以下要求:


  • 国际学生需要完成文件注册过程,但国内学生没有。

StudentStatus界面:

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 
        }
    }
}

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

Before I continue, I understand that this is a really over simplified application process. In the real world, a lot more has to happen before a Student can register. The student may have to go through entrance exams, and payment before registration begins. Also, in a realistic environment, this information would probably be stored in a database that the campus employees can access.

在另一个论坛中,对话进入了正在发出的信息,并给出了方法。

In the other forum, the conversation went into what information is being given out, and approaches were given.


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

我遇到的问题是,您是否仍然需要使用 retriveStatus()向学生询问他/她的状态,或者 isVerified(),我真的不知道如何以其他方式做到这一点。

The problem I have with this, is you're still going to have to ask the Student his/her status either with the retriveStatus() or isVerified(), I don't really see how to do it any other way.


  • 分别将学生和文件集合传递给地图。

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

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(学生)建议上面的方法时,他们说这不是一个好主意,因为规则可以改变,你将不得不改变学生班级以及大学班级。

When I suggested the approach above with the add(Student student) they stated it wasn't a good idea because the rules can change, and you'll have to change the Student class as well as the University class.

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

However, in the real world, a student is well aware of his/her status and if he/she is domestic/international and in possession of documents that can be given to the school.

鉴于上述方法,这样写一个add方法是个好主意吗?有没有比add方法更好的方法?

Given the above approach, is writing the add method this way a good idea? Is there a better approach than the add method?

tl; dr - 如果学生必须遵守大学规定的规则,那么Student对象是否会与大学沟通以获取数据,以便大学可以确保学生对象符合规则而不破坏封装?

tl;dr - If a Student has to follow the rules set by the University, how then would the Student object communicate with the University to get the data so that the University can ensure the student object is complying with the rules without breaking encapsulation?

推荐答案

上一篇文章中的对话可能会引导您走向一个良好的方向。最适用的原则是开放/封闭原则。 https://en.wikipedia.org/wiki/Open/closed_principle

The conversation in previous post was probably leading you in a generally good direction. The principle that applies most is the Open / Closed principle. https://en.wikipedia.org/wiki/Open/closed_principle.

不要让自己不得不经常修改一个特定的类或一组类(至少在OO世界中),你知道它将成为一个常见的向量变化这个原则同样适用于功能世界,但你的例子是使用OOPL。

Don't set yourself up to have to constantly modify a particular class or set of classes (in OO world at least) in an area you know is going to be a frequent vector of change. The principle applies equally in the functional world, but your example is using an OOPL.

很少的手工构建规则引擎对于你提出的问题是一个非常好的解决方案。特别是如果你知道规则在非常固定的输入上流动 - 比如大学和学生。 DocumentsRequiredForInternationalStudents是该体系结构中的规则类 - 只有在该规则本身发生变化时才需要更改。新规则将发生很多=添加新类,而不是修改现有规则。

Little hand-built rules engine is a pretty good solution for your stated problem. Particularly if you know the rule flows on pretty fixed inputs - like the University and the Student. DocumentsRequiredForInternationalStudents is a rule class in that architecture - only needs to change if something about that rule itself changes. New rule, which is going to happen a lot = add new class, not modify existing one.

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

Sometimes you don't know vector of change, harder to make decisions, but if it's obvious, don't architect a system where you'll have to violate open/closed constantly due to an known change vector.

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

There are different ways to implement little rules engines. One option (this is crappy pseudo-code so it takes less space)

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

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

That's just one way to throw it together, but you can see it's not really a lot of code. You have an interface, an implementation class for each rule, and a little rules engine class that applies each rule for you. New rule = new class, modify your constructor in the rules engine to add an instance of that class, done.

此模式当规则中所需的属性和行为非常多样化而不是集中在同一小组类中时,会开始有点挣扎。

This pattern begins to struggle a bit when the properties and behavior that are needed in the rules are very diverse and not concentrated in the same small set of classes.

这篇关于OOP类责任的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆