本文通过示例来谈谈慎用缺省构造函数的一种设计场景。——以JAVA为例展开讨论。
为了便于讨论,我们假定需要建模一个Student,包括姓名和出生地两个属性。我们看到不少下面的代码:
public class Student { private String name = null; private String birthPlace = null; public Student() { } public void setName(String name) { this.name = name; } public void setBirthPlace(String birthPlace) { this.birthPlace = birthPlace; } public String getName() { return name; } public String getBirthPlace() { return birthPlace; } }
使用的例子:
import org.junit.Test; public class StudentTest { @Test public void test() { final String NAME = "John"; final String BIRTH_PLACE = "Hawaii"; Student student = new Student(); student.setName(NAME); student.setBirthPlace(BIRTH_PLACE); assert(NAME.equals(student.getName())); assert(BIRTH_PLACE.equals(student.getBirthPlace())); } }
通常的使用方法就是先用缺省构造函数new出一个对象,然后再调用每个属性的setter方法。
对于以上的设计方法,其适合的语义是:
- 对象的每个属性可以有缺省值,而且缺省值是有意义的;
- 对象的属性值是可变的,即可以通过setter来修改当前的属性值。
符合这种语义的对象非常多,比如表示(二维)平面上的一个点Point2d就适合用上面的设计方法。
本文讨论的是另外一种情况,即有如下语义要求:
- 对应的每个属性没有合适的缺省值;
- 一旦要创建一个对象,那么此时它的各个属性取值也是明确的;
- 属性的值不可更改。
对于我们前面给出的Student例子,我们假定Name不能修改,如果有新的名字,就需要新增一个属性(如aliasName)来表示;而出生地也是固定的。对于这种情况,虽然前面给出的代码也能够较好地工作,但从设计语义上来讲,是不太合适的。
对于这种情况,通常推荐如下的做法:
- 不提供缺省构造函数(C++中必须要定义或声明一个private的缺省构造函数);
- 提供带参数的构造函数,参数列表包括了必须在创建对象时就要指定的属性值;
- 对于不可修改属性值的数据成员,不能提供getter方法。
因此,前面的class Student需要重构成下面的代码:
public class NewStudent { private String name = null; private String birthPlace = null; public NewStudent(String name, String birthPlace) { this.name = name; this.birthPlace = birthPlace; } public String getName() { return name; } public String getBirthPlace() { return birthPlace; } }
使用示例:
@Test public void testNewStudent() { final String NAME = "John"; final String BIRTH_PLACE = "Hawaii"; NewStudent student = new NewStudent(NAME, BIRTH_PLACE); assert(NAME.equals(student.getName())); assert(BIRTH_PLACE.equals(student.getBirthPlace())); }
额外的好处:通过设计优化,我们在创建对象时,有3条语句变成了1条语句;如此,大脑的思考成本显著降低。
——要知道,通常一个项目都有大量的代码,数千上万是非常常见的事情。当遍地充斥着各种各样低质量语义的代码时,整个项目就会产生大量的无效代码,这对于项目维护是一件很可怕的事情。
我们写的每一行代码,都是在向读者(包括你自己)表达一种设计思想。可以工作的代码未必是质量优秀的代码,显然我们要追求的是后者。
时间: 2024-12-27 09:14:20