2011-12-20 10 views
0

私は抽象的なファクトリクラスの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)について方法は、作成方法内で行う必要がありますか?さもなければ、そのような実装の詳細について工場が認識しているか依存しているべきか?

学生バリデータを作成するときにスイッチ(studentType)ステートメントを避けるための解決策があるのであれば、私は感謝します - 私の頭の上にあるアイデアは、内部的に管理されたマップを持ち、反射。

このような手法を使用する利点は、バリデーターを(依存性注入によって)テストするのがはるかに簡単であることです。

答えて

0

を分離し、サービス・インターフェースStudentValidatorServicereadValiationMapFromPersistentOrCachedStorage(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の実装を書くことができます。あるいは、テストのための模擬実装を書くこともできます。実装は使用法から切り離されています。


列挙型を使用して、それを反転、スイッチケースを削除するには:

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

これは、提供されたコードのために改良したものであるが、それは質問に答えていません。生徒の妥当性検査のための工場への依存が必要か、学生タイプの**スイッチ**を避けることでより良い解決策がありますか?私は、より疎結合された機能を実装する方法を探しています。 –

+0

@marius_neo:あなたの質問に「switch statement issue」は言及していませんでした。 – home

+0

@homeあなたは正しいです。私は今これをしました。 –

関連する問題