대개의 경우 우리는 Service 패키지를 구성할 때, OrderService
인터페이스와 OrderServiceImpl
구현 클래스로 구분하여 작성하곤 합니다.
이 방식은 Loose Coupling
을 위한 개발 방식이라고 이해하고 있는데, 엔터프라이즈 레벨이 아닌 일반적인 토이프로젝트에서는 그 구조가 단순히 인터페이스와 구현 클래스가 1개씩 존재하는 구조라서 큰 의미가 없어보이곤 합니다.
그래서 이러한 방식이 어느 순간은 무의미한 노동이 아닐까 하고 의문이 생길 수 있을 것 같습니다. 하지만 그럼에도 불구하고, 인터페이스와 구현 클래스를 구분하는 방식은 그 이유와 목적이 분명한 개발 기법이라고 생각합니다.
개발자는 언제든 구현 로직이 달라질 수 있음을 염두하고 개발을 해야 한다고 생각하는데요, Interface
-Impl
구조를 가져가게 되면 인터페이스를 정해두고 해당 구현을 여러 모듈로 할 수 있습니다.
이는 하나의 인터페이스에 대하여 독립된 구현체를 여러 개 사용할 수 있게 되어 개발 환경에서의 모듈과 실제 배포 단계에서의 모듈 로직을 다르게 구성하면서도, 이를 사용하는 레벨에서는 같은 결과를 보장할 수 있습니다.
이는 구현체와 인터페이스를 구분함으로써 유연성을 확보한다고도 이해할 수 있습니다.
인터페이스는 이 모듈을 사용하는 이가 확인하는 영역이면서, 그 구현체의 설계도이기도 합니다.
우리가 JPA를 직접 사용할 때 조차도 EntityManager(인터페이스 - 구현체는 Hibernate의 Session 클래스)를 사용하듯이, Service 모듈을 사용하는 코드를 구성하는 사람이 본인이 아닐 수 있음을 가정한다면, Controller를 구성하는 사람이 꼭 구현체를 이해할 필요는 없는 겁니다. Controller 로직 개발하는 담당자는 굳이 Service 구현체의 복잡한 로직을 이해하면서 피로감을 느낄 필요 없이, 그 인터페이스만으로 기능을 이해하고 본인의 Controller 로직을 구성할 수 있으면 되는 거죠.
또한 해당 인터페이스를 팀장 급이 설계해주면 그 인터페이스의 설계 의도에 맞춰 구현체 작업을 다른 개발자가 할당받을수도 있습니다.
*"다른 모듈은 interface가 없나?" 하는 부분인데, entity
의 경우 dto
가 존재하고, controller
는 사실 컨트롤러에게 요청을 할당하는 dispatcherServlet
을 제가 작성하지 않으니 굳이 인터페이스를 작업할 필요가 없다고 이해하고 있습니다. repository
또한 이미 dataJPA를 사용하게 되니 논외로 하겠습니다. repository 패키지의 경우 custom하게 되면 보통 custom
이라는 인터페이스와 customImpl
구현 클래스로 나누긴 합니다.
어찌보면 관습처럼 "이렇게 해라!" 와 같이 배우고 넘어가게 되는데, 알면 알수록 그 장점이 분명한 개발 기법이라 굳이 무시할 이유를 아직 찾지 못하는 것 같습니다. 위에서 서술한 이유 중 1번은 자바 프로그래밍 시에 고려해야 하는 Loose Coupling과도 관련이 깊은 내용이니 한번 알아보는 것도 좋을 것 같습니다!ㅎㅎ