Service와 ServiceImpl
Service 인터페이스와 ServiceImpl 구현체 클래스를 나누는 이유
다형성과 OCP(Open Closed Principle)
이론상으로 인터페이스와 구현체가 나눠져있으면 구현체는 외부로부터 독립된다. 이로 인해 구현체의 수정이나 확장이 자유로워지고, 이를 사용하는 클라이언트의 코드에는 영향을 주지 않는다. 예를 들어, 사용자의 동작을 정의하는 서비스가 존재할 때 관리자와 일반 사용자의 경우와 같이 사용자의 권한에 따라 동작이 다른 경우가 있다. 이 경우에는 구현체만 추가하면 추가적인 코드 수정 없이 손쉽게 동작을 추가 할 수 있다.
관습적인 추상화의 장점과 단점
인터페이스와 구현체를 분리하여 얻을 수 있는 장점은 구현체 클래스를 변경하거나 확장하더라도, 이를 호출하는 클라이언트 코드에는 영향을 주지 않는다는 점이다.
클라이언트 코드를 호출부라 부른다면, Service Layer 입장에서는 서비스 클래스를 호출하는 컨트롤러 클래스가 클라이언트 코드일 수 있다. Service layer 의 구현체 클래스를 변경하거나 교체했다고 가정해보자. (ex, AServiceImpl -> BServiceImpl)
클라이언트인 컨트롤러 입장에서는 어차피 의존주입하는 타입은 IService 라는 인터페이스고, 여기에 정의된 추상 메서드는 변하지 않는다.
본디 자바에서 인터페이스를 사용하는 이유는 객체지향 특징 중 하나인 다형성때문이다.
다형성: 하나의 자료형에 여러가지 객체를 대입하여 다양한 결과를 얻어내는 성질
인터페이스
// Interface
public interface IService {
String test();
}
구현체
@Service
public class AServiceImpl implements IService {
@Override
public String test() {
return "AServiceImpl";
}
}
컨트롤러
// Controller
@RequiredArgsConstructor
@RestController
public class SampleController {
private final IService service;
@GetMapping("/test")
public String test(){
return service.test();
}
}
위 예시 코드를 보면 컨트롤러는 특정 구현체가 아닌 IService 타입을 의존 주입받고 있다. (물론 특정 구현체인 AServiceImpl 을 의존주입 받아도 괜찮습니다.)
이렇게 구현체가 아닌 인터페이스를 의존받으면 OCP 원칙을 지킬 수 있다.
또 다른 구현체 (BServiceImpl)
public class BServiceImpl implements IService {
@Override
public String test() {
return "BServiceImpl";
}
}
AServiceImpl 와 마찬가지로 IService에 선언된 test() 메서드를 구현하고 있다. 이제 이 클래스에 @Service 어노테이션을 붙이면 스프링 컨테이너에 의해 SampleController 로 의존주입이 된다. ( AServiceImpl 의 @Service 어노테이션은 제거해주어야 한다.)
IService 라는 인터페이스를 구체화 하는 구현체간의(AServiceImpl, BServiceImpl) 차이만 있을 뿐, 클라이언트 코드(컨트롤러) 입장에서는 무엇이 변했는지 전혀 모르는 상태이다. 여기서 모르는 상태라는 것은, ServiceLayer 의 구현체가 변경되더라도 클라이언트 코드는 전혀 수정할 필요가 없다는 의미다. 지금은 단순히 test() 라는 메서드에서 문자열을 출력하는 기능밖에 없어 감흥이 없을 수 있다. 유명한 예제인 정률 할일(%할인) 정액 할인(1000원 할인) 을 생각해보자. 만약 현재는 정률 할인을 진행하더라도, 갑자기 정액할인으로 정책이 변경된다면, 위의 예제처럼 서비스레이어의 어노테이션만 바꿔주면 간단하게 변경된 정책을 코드상 배포할 수 있게 된다.
출처 : https://colabear754.tistory.com/109
https://junior-datalist.tistory.com/243