【发布时间】:2017-10-30 21:45:13
【问题描述】:
我正在开发一个爱好项目,以正确理解封装、可以负责的类和规则。我在另一个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) 建议上述方法时,他们表示这不是一个好主意,因为规则可能会改变,您必须更改 Student 类以及 University 类。
但是,在现实世界中,学生很清楚他/她的身份,以及他/她是国内还是国际,并且拥有可以提供给学校的文件。
鉴于上述方法,以这种方式编写 add 方法是个好主意吗?有没有比 add 方法更好的方法?
tl;dr - 如果学生必须遵守大学制定的规则,那么学生对象将如何与大学通信以获取数据,以便大学可以确保学生对象在不破坏封装的情况下遵守规则?
【问题讨论】:
-
我认为您需要对模型进行一些更改。考虑每个类中应该存在哪些依赖项。例如,学生对象应该知道状态吗?这是我的建议:为学生、状态、文档、大学和注册策略创建抽象。您可以将抽象工厂用于各种注册过程,也可以使用策略。
-
一所大学招收一种类型的学生吗?
-
@AndrewTobilko - 不,但我想专注于国际,因为那是一套规则我无法理解和实施的规则。
-
@amitmah - 从现实世界的角度来看,学生知道身份,您知道自己是国内还是国际,并且有文件证明您的身份。我不明白为什么学生不会意识到这一点。
-
isVerified不应该在Student中。学生无法确认他的验证。此验证可能涉及一些服务。您会将实体绑定到这些服务吗?但是学生可以将文件交给负责决定这些文件是否符合要求的服务机构。学生对要求以及他拥有的文件的结构一无所知。