在Java中放置comprobations的位置?
在创建必须验证条件的对象时,我一遍又一遍地想出这个问题.是否应该在尝试创建对象之前或在对象本身的构造函数中放置检查?
为了更好地说明这一点,这里有一个例子:假设我们有一名学生经理,一位教授,他将学生对象添加到他们的列表中.创建新的学生对象时,我们必须检查他的名字最长为20个字符. class Professor{ LinkedList<Student> studentsList; Professor(){ studentsList = new LinkedList<Student>(); } public Student addStudent(String studentName){ // Place 1 if (studentName.length <= 20) studentList.add(new Student(studentName)); else // Do another thing } } class Student { String name; Student(String studentName){ // Place 2 if (studentName.length <= 20) name = studentName); else // Don't create the object and throw exception } } 所以基本上我的问题是,如果在“地点1”中进行检查,在尝试创建学生之前,或者在“地点2”中,在学生的构造中进行. 解决方法
物体对自己负责
通常在object-oriented programming (OOP),我们希望对象对自己负责.关于其内部国家完整性的业务规则应该在内部处理(或委托给建设者 – 见下文).这个想法是正式在OOP中被称为encapsulation的一部分. 因此,在您的示例中,教授课程不应该担心学生班级的规则,例如学生姓名的长度.学生班应该强制执行自己的诚信.我们希望这些完整性规则的逻辑位于一个单独的位置,而不是分布在整个应用程序中. 实际上,教授类不应该实例化Student对象.在你的例子中暗示,必须有一些其他方将学生分配给教授.也许是一个 当学生对象到达教授时,它们应该是有效的.教授课程不应该关注学生的有效性.教授应该只关心教授的有效性与否. class Professor{ List< Student > students; … public void addStudent( Student student ){ Objects.requireNonNull?( student,"Received NULL rather than a Student object. Message # 68a0ff63-8379-4e4c-850f-e4e06bd8378a." ) ; // Throw an exception if passed a null object. Objects.requireNonNull?( this.students,"Collection of Student objects is NULL. Message # c22d7b22-b450-4122-a4d6-61f92129569a." ) ; // Throw an exception if the `students` list is not established. this.students.add( student ) ; } } 除了对象对自己负责的想法之外,教授没有实例化Student对象的另一个原因是为了方便testing.如果Student对象来自其他来源,那么该源可以使用Student类或非接口提供虚假对象.尚未完成,禁用某些功能(如数据库访问),或者替换为为测试场景而设计的伪造数据. 生成器模式 如果您有多个需要验证的属性才能实例化新对象,您可能需要使用Builder pattern.您可以定义一个额外的类,例如StudentBuilder,它具有创建学生所需的每个部分的方法. 通常,这些方法都返回相同的StudentBuilder对象以方便call-chaining. 不同的人对于建造者有不同的风格.一种方法是提供有效性检查方法,也许是提供阻止构建所需对象的问题列表的方法. 有些人使用类似于而不是访问器方法设置的单词来清楚地表明当我们在构建器上临时设置属性时,真正的意图是在另一个类的对象上设置属性. StudentBuilder sb = new StudentBuilder().withFirstName( "Alice" ).withLastName( "Coleman" ).withEmail( "x@y.com" ); if( sb.isValid() ) { Student s = sb.build() ; … } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |