2012-01-19 2 views
25

필자는 실제 서비스 및 DAO 클래스와 동일한 인터페이스를 가진 몇 가지 봄 - 최대 절전 웹 응용 프로그램 프로젝트를 보거나 보았습니다.항상 서비스 및 DAO 레이어에 단일 구현 인터페이스가있는 이유는 무엇입니까?

나는 항상 생각하는이 하나의 구현 인터페이스를 가진 주요 원인으로 두 가지 :

  1. 봄이 지정된 클래스 (느슨한 결합)에 종속 등의 실제 구현을 연결할 수 있습니다

    public class Person { 
        @Autowired 
        private Address address; 
    
        @Autowired 
        private AccountDetail accountDetail; 
    
        public Person(Address address, AccountDetail accountDetail) 
        { // constructor 
    
  2. 유닛 테스트 중에 mock 클래스를 만들고 클래스를 독립적으로 테스트 할 수 있습니다. EasyMock에 같은

    public class Person { 
    
    @Autowired 
    private AddressImpl address; 
    
    @Autowired 
    private AccountDetailImpl accountDetail; 
    
    public Person(AddressImpl address, AccountDetailImpl accountDetail) { 
    // constructor 
    

    모의 프레임 워크 구체적인 클래스뿐만 아니라

    을 조롱 할 수 있습니다

    봄 종속성으로 구체적인 구현 클래스를 연결할 수 있습니다 :

    Address mockedAddress = mock(Address); 
    AccountDetail mockedAccountDetail = mock(AccountDetail); 
    Person underTestPerson = new Person(mockedAddress, mockedAccountDetail); 
    // unit test follows 
    

는하지만, 늦게, 나는 것을 깨달았

AddressImpl mockedAddress = mock(AddressImpl); 
AccountDetailImpl mockedAccountDetail = mock(AccountDetailImpl); 
Person underTestPerson = new Person(mockedAddress, mockedAccountDetail); 
// unit test follows 

또한, this 논의에 따르면, 요약하면 단일 응용 프로그램 내에서 인터페이스가 협약이나 습관에서 대부분 과용됩니다. 일반적으로 전 세계 여러 응용 프로그램에서 사용되는 slf4j와 같은 다른 응용 프로그램과 인터페이스 할 때 가장 적합합니다. 단일 응용 프로그램 내에서 클래스는 인터페이스와 거의 동일한 추상화입니다.

내 질문에 우리는 여전히 인터페이스가 필요하고 * ServiceImpl 및 * DaoImpl 클래스와 같은 단일 구현을 갖고 불필요하게 코드 기반 크기를 늘리는 것입니다. 내가 알지 못하는 구체적인 수업을 조롱하는 데 문제가 있습니까?

언제든지 팀 동료와 이야기했지만, 인터페이스에 기반한 서비스 및 DAO 클래스를 구현하는 것은 모두가 따르는 디자인입니다. 스프링 권장 사항, OOP, DDD 등을 언급합니다.하지만 격리 된 응용 프로그램 내에서 너무 많은 인터페이스가있는 이유는 아직 실용적인 이유가 없습니다.

+2

대답에 관해서는 - 나는 각 개체 앞에 인터페이스를 던지는 이유 때문에 DDD를 어떻게 호출 할 수 있는지 보지 못했습니다. DDD는 그 일과 관련이 없습니다. OOP조차도 열악한 근거가됩니다. L, I, D와 같은 것들을 SOLID와 같이 사용한다면 인터페이스와 같은 추상화를 어떻게 디자인해야 하는지를 지정합니다. * 항상 사용해야하는 것은 아닙니다. 당신이 말했던 것처럼 나는 그것이 모두 "봄 최고의 연습"에 버틸 수 있다고 생각하거나 습관적으로 그렇게하는 사람들입니다. – guillaume31

답변

14

인터페이스에 더 많은 장점이 있습니다. 프록시시와 마찬가지입니다. 클래스가 인터페이스를 구현하면 JDK 동적 프록시가 AOP에 기본적으로 사용됩니다. 구현을 직접 사용하면 proxy-target-class = true로 설정하여 CGLIB 프록시를 사용해야합니다. JDK 프록시와 달리 바이트 코드 조작이 필요합니다.

자세한 내용은 here을 참조하십시오.

자세한 내용은 what reasons are there to use interfaces (Java EE or Spring and JPA)에서 다른 토론을 읽어보십시오.

14

매우 논쟁의 대상입니다. 간단히 말해, 적어도 개발자에게는 아무 것도 없습니다.

EJB2 세계에서 가정과 원격 인터페이스는 필수 요소 였고 @AravindA가 다음과 같이 언급했습니다. 프록시 : 프록시. 보안, 리모팅, 풀링 (pooling) 등 모든 것을 프록시로 감싸고 표준 라이브러리 내에서 엄격하게 요청 된 서비스를 제공 할 수 있습니다 (DynamicProxy).

우리는 javaassistcglib을 가지므로 Spring (Hibernate, EJB3)은 프레임 워크 개발자가 좋아하는 클래스를 완벽하게 구현할 수 있습니다. 문제는 매개 변수가없는 생성자를 추가하도록 요청하는 것입니다 .- 잠깐, 여기에 매개 변수가 있습니까? - 단, 생성자를 추가하지 마십시오.

인터페이스가 정상적으로 유지되도록 여기에 있습니다. 그래도 이상하지 않은데, 적절한 생성자를 가진 클래스의 인수가없는 생성자는 내게 의미가있는 것이 아닙니다. 맞습니까? Spring이 클래스의 인터페이스와 동등한 기능을 생성한다는 사실을 밝혀 줘야한다. 즉, (또는 무시 된) 상태가없는 인스턴스와 모든 메소드가 무시된다. 따라서 "실제"인스턴스와 "가짜 인터페이스"가 있으며, 가짜 인터페이스는 모든 보안/트랜잭션/원격 처리 기능을 제공합니다. 멋지지만 이해하기 어렵고, 별개로 생각하지 않으면 버그처럼 보입니다.

또한 클래스에 인터페이스를 구현하면 (적어도 일부 버전의) Spring이 갑자기이 인터페이스 만 프록시하려고 결정하고 응용 프로그램이 명백한 이유없이 작동하지 않습니다.

따라서 지금까지의 이유는 안전성과 온전함입니다. 좋은 연습이 필요한 이유가 있습니다.하지만 게시물에서 나는 이미 그 모든 것을 읽었습니다. 오늘 볼 수있는 가장 중요한 이유는 WTH/분 측정 항목입니다. 특히 프로젝트 신규 사용자에 대해 이야기하는 경우 더욱 그렇습니다.

관련 문제