我有一个抽象工厂类StudentValidatorFactory,它被假定为(根据指定参数)创建必须注入验证映射的各种StudentValidator类实例(参见下面的代码)。
public class StudentValidatorFactory{
public static final int JUNIOR_STUDENT_TYPE = 1;
public static final int SENIOR_STUDENT_TYPE = 2;
public StudentValidator createStudentValidator(int studentType) throws StudentValidatorCreationException{
Map<String,ValidationBean> validationMap = readValiationMapFromPersistentOrCachedStorage(studentType);
switch (studentType){
case JUNIOR_STUDENT:
return new JuniorStudentValidator(validationMap);
case SENIOR_STUDENT:
return new SeniorStudentValidator(validationMap);
}
}
}
public interface StudentValidator{
void validate(Student student) throws StudentValidationException;
}
public class JuniorStudentValidator{
private Map<String, ValidationBean> validationMap;
public JuniorStudentValidator(Map<String,ValidationBean> validationMap){
this.validationMap = validationMap;
}
public void validate(Student student) throws StudentValidationException{
// make use of validation map for apply junior student related validations on the student
}
}
public class SeniorStudentValidator{
private Map<String, ValidationBean> validationMap;
public SeniorStudentValidator(Map<String,ValidationBean> validationMap){
this.validationMap = validationMap;
}
public void validate(Student student) throws StudentValidationException{
// make use of validation map for apply senior student related validations on the student
}
}
我的问题是关于 StudentValidatorFactory.createStudentValidator(int studentType)方法是否应该在create方法中从持久存储中读取验证图(基于学生类型)?否则说,工厂应该知道/依赖这些实施细节吗?
我很欣赏在创建学生验证器时是否会有一个避免切换(studentType)语句的解决方案 - 我的想法是拥有一个内部管理的地图并通过反射执行StudentValidator具体类实例化
使用这种技术的好处是验证器更容易被测试(通过依赖注入)。
答案 0 :(得分:0)
在分离的服务接口readValiationMapFromPersistentOrCachedStorage(studentType)
中提取StudentValidatorService
,并使用属性或构造函数参数在StudentValidatorFactory
中注入服务实例:
public interface StudentValidatorService {
Map<String,ValidationBean> getValidationMap(int studentType);
}
public class StudentValidatorFactory{
public static final int JUNIOR_STUDENT_TYPE = 1;
public static final int SENIOR_STUDENT_TYPE = 2;
public StudentValidatorFactory(StudentValidatorService studentValidatorService) {
this.studentValidatorService = studentValidatorService;
}
public StudentValidator createStudentValidator(int studentType) throws StudentValidatorCreationException{
Map<String,ValidationBean> validationMap = studentValidatorService.getValidationMap(studentType);
switch (studentType){
case JUNIOR_STUDENT:
return new JuniorStudentValidator(validationMap);
case SENIOR_STUDENT:
return new SeniorStudentValidator(validationMap);
}
}
}
现在您可以编写由数据库支持的StudentValidatorService
实现。或者你可以编写一个模拟实现进行测试。现在,实现与使用情况分离。
要移除开关盒,请使用枚举:
将其反转public enum StudentType {
JUNIOR_STUDENT {
public StudentValidator getValidator(Map<String,ValidationBean> validationMap) {
return new JuniorStudentValidator(validationMap);
}
},
SENIOR_STUDENT {
public StudentValidator getValidator(Map<String,ValidationBean> validationMap) {
return new SeniorStudentValidator(validationMap);
}
};
public abstract StudentValidator getValidator(Map<String,ValidationBean> validationMap);
}
public class StudentValidatorFactory{
public StudentValidatorFactory(StudentValidatorService studentValidatorService) {
this.studentValidatorService = studentValidatorService;
}
public StudentValidator createStudentValidator(StudentType studentType) throws StudentValidatorCreationException{
Map<String,ValidationBean> validationMap = studentValidatorService.getValidationMap(studentType);
return studentType.getValidator(validationMap);
}
}