【问题标题】:Is it good to insert database access dependency in an abstract factory?在抽象工厂中插入数据库访问依赖关系好吗?
【发布时间】:2011-12-20 12:32:36
【问题描述】:

我有一个抽象工厂类 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 方法中从持久存储(基于学生类型)读取验证图?否则,工厂是否应该了解/依赖此类实施细节?

如果在创建学生验证器时有避免 switch(studentType) 语句的解决方案,我将不胜感激 - 我的想法是拥有一个内部管理的映射并通过反射执行 StudentValidator 具体类实例化.

使用这种技术的优点是验证器更容易测试(通过依赖注入)。

【问题讨论】:

    标签: java dependency-injection abstract-factory


    【解决方案1】:

    在分离的服务接口StudentValidatorService 中提取readValiationMapFromPersistentOrCachedStorage(studentType),并使用属性或构造函数参数在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 的实现。或者您可以编写一个模拟实现进行测试。现在实现与使用分离。


    要删除 switch-case,请使用枚举反转它:

    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);
        }
    }
    

    【讨论】:

    • 这是对所提供代码的改进,但它没有回答问题。学生验证检索是否需要依赖工厂,或者通过避免学生类型的 switch 是否有更好的解决方案?我正在寻找一种方式来实现更松耦合的功能。
    • @marius_neo:您的问题中没有提到“switch statement issue”。
    猜你喜欢
    • 1970-01-01
    • 2015-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    相关资源
    最近更新 更多