2008-09-24 5 views
6

This question about unit testing best practices에는 종속성 삽입을위한 클래스 설계가 언급되어 있습니다. 이것은 정확하게 그것이 무엇을 의미하는지에 관해 생각하게했다.종속성 주입을위한 클래스 설계 지침

제어 컨테이너의 반전 작업을 시작한 지금이 문제에 대한 아이디어가 몇 가지 있습니다. 따라서 벽에 던져서 무엇이 붙어 있는지 보겠습니다.

내가 본 것을 보면, 객체가 가질 수있는 3 가지 기본 종속성 유형이 있습니다.

  1. 개체 종속성 - 문제의 클래스에 의해 사용되는 실제의 객체입니다. 예를 들어 LogInFormController의 LogInVerifier입니다. 이것들은 생성자를 통해 주입되어야합니다. 클래스가 생성자에서 4 개 이상의 객체를 필요로하는 충분히 높은 수준이라면 파열을 고려하거나 적어도 공장 패턴을 사용하는 것이 좋습니다. 또한 인터페이스에 종속성을 제공하고 인터페이스에 대해 코딩하는 것을 고려해야합니다.
  2. 간단한 설정 - 예 : 임계 값 또는 시간 초과 기간. 이들은 일반적으로 기본값을 가져야하며 공장 패턴의 빌더를 통해 설정되어야합니다. 그것들을 설정하는 생성자 오버로드를 제공 할 수도 있습니다. 그러나 대부분의 경우 클라이언트가 명시 적으로 설정해야하는 것은 아닙니다.
  3. 메시지 개체 -받는 클래스가 비즈니스 논리에 아마도 사용하는 한 클래스에서 다른 클래스로 전달되는 개체입니다. 예를 들어 LogInCompleRouter 클래스의 User 객체가 있습니다. 여기서는 생성자에서 메시지를 지정하지 않는 것이 더 좋습니다 (즉, 전역으로 만드는 IoC 컨테이너에 User 인스턴스를 등록하거나 User 인스턴스가있을 때까지 LogInCompleteRouter를 인스턴스화하지 않아야 함). (DI를 사용할 수 없거나 적어도 컨테이너에 대한 명시 적 종속성이 필요합니다). 이 경우 메서드 호출 (예 : LoginInCompleteRouter.Route (User u);)에 필요할 때만 메시지 객체를 전달하는 것이 좋습니다.

또한, 나는하지 모든이 DI'ed해야한다고 언급해야 당신이 던져 - 멀리 클래스에 밖으로 요인 단지 편리하다고 기능의 간단한 비트가 있다면, 아마 인스턴스화 괜찮습니다 그 자리에. 분명히 이것은 판결 요청입니다; 나는 그것이 편법

class PasswordEqualsVerifier { 
    public bool Check(string input, string actual) { return input===actual;} 
} 

같은 클래스를 작성 알게되면 아마 그것을 주입 의존성을 귀찮게하지 않을 그냥 객체가 사용하는 블록 내부에 직접 인스턴스화 할 것입니다. 결과적으로 단위 테스트를 작성할 가치가 있다면 주입하는 것이 좋습니다.

그럼 너희들은 어떻게 생각하니? 추가 지침이나 대조적 인 의견을 환영합니다.

답변

1

중요한 것은 인터페이스에 코드를 작성하고 클래스가 인스턴스를 작성하는 대신 해당 인터페이스의 인스턴스를 허용하도록하는 것입니다. 분명히 이것으로 미칠 수 있지만 단위 테스트 나 DI에 관계없이 일반적인 좋은 습관입니다.가 찬성 클래스에서이 문제를 제거하기 위해 더 좋을 것이다, 그러나

public class BaseDAO 
{ 
    public BaseDAO(String connectionURL, 
        String driverName, 
        String username, String password) 
    { 
     // use them to create a connection via JDBC, e.g. 
    } 

    protected Connection getConnection() { return connection; } 
} 

: 당신이 데이터 액세스 개체가있는 경우

예를 들어,이 같은 모든 DAO를위한 기반을 작성하는 경향이있을 수 있습니다 인터페이스의

public interface DatabaseConnection 
{ 
    Connection getConnection(); 
} 

public class BaseDAO 
{ 
    public BaseDAO(DatabaseConnection dbConnection) 
    { 
     this.dbConnection = dbConnection; 
    } 

    protected Connection getConnection() { return dbConnection.getConnection(); } 
} 

이제 DatabaseConnection의 다중 요소를 제공 할 수 있습니다. 단위 테스트를 무시하는 경우에도 JDBC를 사용한다고 가정하면 Connection을 가져 오는 두 가지 방법이 있습니다. 컨테이너에서 연결 풀을 만들거나 드라이버를 사용하여 직접 연결하는 것입니다. 자, DAO 코드는 두 전략 중 하나와 결합되지 않습니다.

테스트를 위해 코드를 테스트하기 위해 미리 준비된 데이터를 사용하여 일부 내장 JDBC 구현에 연결하는 MockDatabaseConnection을 만들 수 있습니다.