在回答您的问题之前,我想解释一下构建器模式。
当您有很多重载的构造函数(伸缩构造函数反模式)时,通常会使用构建器模式。例如
public class Employee {
public Employee(String firstName, String lastName){
...
}
public Employee(String firstName, String lastName, Sex sex){
...
}
public Employee(String firstName, String lastName, String salutation) {
...
}
}
在这种情况下,客户端代码必须根据它拥有的数据来决定调用哪个构造函数。如果它有 afirstName
并且lastName
它必须调用new Employee(firstName, lastName)
. 如果它只有一个firstName
它必须调用Employee(String firstName)
. 所以客户端代码可能有很多if/then/else。例如
Employee employee = null;
if(firstName != null && lastName != null && sex != null){
employee = new Employee(firstName, lastName, sex);
} else if(firstName != null && lastName != null && salutation != null){
employee = new Employee(firstName, lastName, salutation );
} else {
.....
}
Employee
这个例子中的类的设计包括它firstName
并且lastName
是 的强制属性Employee
,因为每个构造函数都需要它们。属性sex
和saluation
是可选的。如果客户端代码决定调用哪个构造函数,这也意味着决策过程在客户端代码中重复。例如,如果客户端知道firstName
,和它应该调用哪个构造函数?要么要么?lastName
sex
salutation
new Employee(firstName, lastName, sex)
new Employee(firstName, lastName, saluation)
为了封装构造函数解析,您可能需要使用构建器模式。
public class EmployeeBuilder {
public EmployeeBuilder(String firstName, String lastName){
}
public void setSex(Sex sex){ ... }
public void setSalutation(Salutation salutation){ ... }
public Employee build(){
if(salutation != null){
return new Emplyoee(firstName, lastName, salutation);
} else if(sex != null){
return new Emplyoee(firstName, lastName, sex);
} else {
return new Emplyoee(firstName, lastName);
}
}
}
这使得客户端代码更易于阅读,并且封装了构造函数调用决策。例如
EmployeeBuidler employeeBuilder = new EmployeeBuilder(firstName, lastName);
Sex sex = ...;
String salutation = ...;
employeeBuilder.setSex(sex);
employeeBuilder.setSalutation(salutation);
Employee employee = employeeBuilder.build();
回到你的问题
那么在这种情况下真的值得付出努力吗?
对于您的单元测试,您可能希望创建Employee
具有某些属性的对象,而其他属性应设置为默认值。在这种情况下,我认为使用构建器模式是个好主意。然后我会命名构建器,例如EmployeeDefaultValuesBuilder
以使其清楚。
您可能还想Employee
基于其他员工对象(模板)构建 s。在这种情况下,我会向EmployeeBuilder
. 例如
public EmployeeBuilder(Employee template){
// initialize this builder with the values of the template
}
因此,如果您封装构造逻辑或增加可读性,那么值得付出努力。