Spring

[Spring] Service ServiceImpl 구조를 사용하는 것이 바람직한가

빅콜팝 2023. 3. 12. 14:19
728x90
반응형
public interface MemberService{
    Boolean singUp();
}

public class Member implements MemberService {
    @Override
    public Boolean singUp() {
        return true;
    }
}

SpringMVC 구조로 개발 할 때 Service단을 Service, ServiceImpl 즉 인터페이스와 구현체로 구분하여 개발을 했었는데
오픈 소스를 분석하는 도중 Service단을 인터페이스-구현체 구조가 아닌 Service 클래스를 단일로 사용하는 구조가 많이 보였다.

 

Spring Framework에서 Service와 ServiceImpl 구조를 사용하는 이유는 무엇일까?


 

1. 인터페이스와 구현 클래스를 분리할 수 있다.



 이를 통해 코드의 유연성과 확장성이 증가하며, 유지보수성이 향상된다. Service 인터페이스는 비즈니스 로직을 담당하고, ServiceImpl은 Service 인터페이스를 구현하여 실제 로직을 처리한다.

이를 통해 비즈니스 로직과 구현 로직을 분리함으로써 각각을 독립적으로 개발하고 테스트할 수 있게 된다.

이는 또한 향후 구현 변경이 필요한 경우 인터페이스만 수정하면 되므로 유지보수성이 높아지는 장점이 있다.

 

 


2. 스프링 프레임워크가 제공하는 IoC(Inversion of Control) 기능과 함께 사용할 수 있다.


 스프링은 IoC 기능을 통해 객체 생성과 의존성 주입을 관리하며, 이를 통해 객체 간의 결합도를 낮추고 유연성과 확장성을 높일 수 있다. 

Service와 ServiceImpl 구조를 사용하면 Service 인터페이스를 빈으로 등록하고, 이를 ServiceImpl에서 의존성 주입받아서 사용하는 방식으로 구현할 수 있다. 

이를 통해 의존성 주입을 스프링이 관리하도록 만들어 IoC를 구현할 수 있다.

 

 

3. 과거의 관습이 현재까지 이어져왔다.


과거 2.0 Spring에서는 AOP Proxy를 구현할 때 JDK Dynamic Proxy를 사용했다.

JDK Dynamic Proxy는 인터페이스를 구현한 객체에 대해서만 AOP Proxy를 생성할 수 있었다.

그러나 시간이 지나면서 인터페이스를 구현하지 않은 클래스에 대해서도 AOP Proxy를 생성할 수 있는 CGLIB가 포함되면서 인터페이스-구현체 관계가 아닌 클래스에 대해서도 AOP 구현이 가능해졌다.

 

- Spring AOP Proxy : 런타임 시점에 원래 객체의 기능을 감싸서 대신 호출하며, 메소드 호출 전후에 공통적으로 수행되어야 하는 로직(Advice)을 삽입합니다. 이러한 AOP Proxy를 사용하여 스프링은 애플리케이션에서 공통적으로 발생하는 문제를 해결하고, 유지보수 및 확장성을 높일 수 있게 해 준다.

 

 

 

그렇다면 Serivce ServiceImpl 구조를 사용하지 않아야 하는 이유에 대해서도 살펴보자


 

1.  불필요한 추상화


service와 serviceImpl 구조를 사용하면 인터페이스와 구현 클래스 간의 불필요한 추상화가 추가된다. 

이 경우, 단순한 기능을 가진 서비스에서도 인터페이스와 구현체를 생성해야 하므로 코드의 복잡도가 증가할 수 있다.

 

2.  중복 코드 발생


단순한 CRUD 기능을 수행하는 경우에는 인터페이스와 구현체를 생성하지 않아도 충분하다. 

이 경우, Service 인터페이스와 ServiceImpl 구현체를 모두 생성하면서 중복 코드가 발생할 수 있다.

 

3.  테스트의 어려움


Service와 ServiceImpl 구조를 사용하면 단위 테스트가 어려울 수 있다. 

이 구조를 사용하면 Service 인터페이스와 ServiceImpl 구현체를 모두 생성해야 하므로 테스트 코드를 작성하기 어렵다. 

또한, 구현체와 인터페이스 간의 의존성이 높아져 테스트 케이스 작성이 복잡해질 수 있다.

 

 

결론적으로 Service ServiceImpl 구조를 사용해야 할까?

OOP 관점에서 봤을 때 인터페이스는 다형성 혹은 개방 폐쇄 원칙 때문에 사용한다. 보통 흔히 얘기하는 느슨한 결합 혹은 유연해지도록 설계하기 위해 사용된다.

그렇다면 Spring에서 Service는 다형성이 필요한가..

본인 경험으로 보았을 땐 다형성이 필요 없는 경우가 대부분이었다. 우리가 사용하는 대부분의 Service는 하나의 Service가 여러 개의 SerivceImpl을 가지고 있는 경우가 아닌 1:1 구조를 띄고 있다.

그러므로 Service를 사용하고, 추후 다형성이 필요해지면 그때 해당 Service에 대해서 인터페이스를 적용해도 늦지 않는 것 같다.

728x90
반응형