2012-02-20 2 views
24

나는 의존성 주입의 모든 힘을 파악하기 위해 시작 인 Java 개발자이며 갑자기 정적 방법을 주입 할 방법이 없다는 것을 알게되었습니다. 그래서 그것은 내 생각을 가지고 : 정적 메서드 DI 안티 패턴입니까?정적 메서드는 DI 패턴이 반대입니까?

더 중요하게 : 종속성 삽입을 채택한다면 정적 메소드 코딩을 중단해야합니까? 나는 그들을 조롱 할 수있는 방법이 없기 때문에 물어 봅니다. 단위 테스트 중에 모의 정체를 주입하는 것은 제게 큰 타격입니다.

편집 : 나는 일반적인 방법은 "포장"기존의 정적 메서드는이처럼 주입하는 것을 알고 :

public class Foo { 
    public static void bar() { ... } 
} 

public interface FooWrapper { 
    public void bar(); 
} 

public class FooWrapperImpl implements FooWrapper { 
    public void bar() { 
     return Foo.bar(); 
    } 
} 

...하지만 기존의 정적을 주입하는 방법을 묻는 게 아니에요 방법 ... 나는 모든 코드 (앞으로부터)가 DI의 개념을 포용한다면, 나는 그것들을 모두 쓰지 말아야하는지 묻는다.

또한 이와 비슷한 질문을 많이하지만 이와 동일한 질문을 한 정확한 일치를 찾을 수 없습니다. 당신이 실제로 다른 질문의 속임수임을 알게되면, 나에게 그것을 지적하십시오. 나는이 질문을 스스로 닫을 것입니다. (그냥 closevote하지 마세요!).

답변

38

정적 메서드는 상태가없는 개체에 적합합니다. 일부 공장 메서드, Math.sin과 같은 "순전히 기능적인"메서드는 모두 완벽하게 허용되는 정적 메서드입니다. java.lang.Mathjava.util.Collections에는 완벽하게 수용 가능한 정적 메서드의 많은 훌륭한 예제가 있습니다.

다행히도 이러한 방법은 종속성 삽입이나 그러한 것들과 상호 작용할 필요가 없습니다. 그들은 테스트하기가 비정상적으로 어렵지 않습니다. 그들은 조롱 등이 필요한 의존성이 없습니다.

정적 상태 또는 정적 상태와 연관된 정적 메서드는 완전히 악조건입니다. 그 입니다.

항상 동등한 입력에 동일한 출력을 반환하는 경우에만 메소드가 비 상태 유지 (따라서 합법적 인 정적 메소드)로 정의되는 데 도움이됩니다. 이는 예를 들어 데이터베이스 쿼리와 파일 시스템 I/O는 파일 시스템이나 데이터베이스의 내용에 따라 출력이 달라지기 때문에 메소드를 상태로 만듭니다.

+0

그래서'fizz()'라는 메쏘드가 있고 그 안에 데이터베이스를 조회하고 내 로컬 파일 시스템에 모든 변경을하는'Widget.buzz()'메쏘드에 대한 정적 호출을합니다. 그러면'widget.buzz() '를 호출하여 발생한 모든 커다란 변화를 호출하지 않고 어떻게'fizz()'를 테스트 할 수 있습니까? 요점은, 나는 정적 인 메소드를 모두 쓰는 것을 멈춰야한다고 생각한다. 그래서 나는 정확한 '위젯'객체 (normal vs mock)를 주입 할 수 있고 런타임에'buzz()'의 "version"이 실행되도록 제어 할 수있다. 생각? – IAmYourFaja

+0

'Widget.buzz()'는 데이터베이스와 암시 적으로 전체 파일 시스템과 정적 상태를 연관시킵니다. 그건 사악 해. 'fizz'는'Widget' 인수를 취할 수 있고'fizz'를 테스트하기 위해'위젯 (Widget) '을 조롱 할 수 있습니다. –

+0

아, 필자는 데이터베이스 또는 파일 시스템이 상태 저장으로 간주하지 않았습니다. "statefulness"를 정의하기 위해 어떤 기준을 사용합니까? 내 오해의 뿌리라고 생각합니다. – IAmYourFaja

2

정적이 아닌 메소드는 종속성 주입과 호환되는 이 아니라입니다. 단순히 싱글 톤의 인스턴스 메소드로 만듭니다.

관련 문제