MVC 패턴으로 개발하고자 하면 자연스레 한 페이지에 5개의 파일이 생성되는데 JSP, Controller, DTO, Service, DAO 입니다.
이중에 Service와 ServiceImpl은 왜 이러한 구조를 가지는지 궁금증을 가지게 되었습니다.
기존 MVC 모델이 가지고자 했던 패턴은 각각의 작업들을 패턴화 시키고 분리하여 역할에 따라 파일들을 분리해서 작업하고자 하였습니다.
여러글들을 찾아본 결과 OOP와 AOP등 객체지향적 설계원칙에 장점이 있다고 하나, 어차피 인터페이스와 구현 클래스간의 관계가 1:1로 구성되게 되어 실질적으로 인터페이스 사용에 대한 이점을 전혀 가져가지못하게 되는데 왜 이러한 구성을 가지게 되었을까?
잘못된 객체지향적 코딩에서 이루어졌다는 관점이다.
MVC패턴이 가진 JSP, Controller, Model등의 구분은 하였지만 Service 클래스의 한 메서드 내에서 모든 비지니스 로직이 진행되는 transaction script 형식의 코딩을 진행한 프로젝트들이 많이 있다는데 중점을 두었다.
사실 우리가 필요한것은 Service 클래스내의 비지니스로직을 처리하는 메서드이고 그것을 처리하는 메서드를 만들기 위해선 자바의 특성상 클래스가 필요하고 그렇게 개발하을 하다보니 그 코드를 확장하여 개발하는것보다는 단순히 그 메서드에 if문을 추가하고, 혹은 일부분을 새로운 코드로 채우는 리팩토링이 된다는 관점이다.
MVC 패턴에서의 핵심은 View는 자신이 요청할 Controller만 알고있으면 되고, Controller는 화면에서 넘어오는 매개변수들을 이용해 Serviec 객체를 호출하는 역할을 한다. Service는 불필요하게 Http 통신을 위한 HttpServlet을 상속 받을 필요도 없는 순수한 자바 객체로 구성된다.(그렇기에 Service 에 request나 response와 같은 객체를 매개변수로 받아선 안된다. 그걸 사용해야하는 작업은 컨트롤러에서 해야한다.)
그렇기에 자신을 어떤 Controller가 호출하든 상관없이 필요한 매개변수만 준다면 자신의 비지니스로직을 처리하게된다. 즉 모듈화를 통해 어디서든 재사용이 가능한 클래스 파일이라는 뜻이다.
또한, 추가적인 요청사항이 들어오면 기존 소스를 수정하는게 아니라 기존 service 인터페이스를 구현한 다른 클래스를 구현해 그 객체를 사용하게끔 하는것이다. OCP에 입각한 변화에는 닫혀있고 확장에는 열려있는 구조로 만들어야한다는 것이다.
Service 인터페이스는 비지니스 로직을 처리하는 모델은 요청사항에 따라 언제든 변할 수 있는 부분이었고 변화에 대응하기 위해 확장을 염두하여 인터페이스로 구성했던것이다. 그런데 어디서부터 잘못된 것인지 Service를 인터페이스로 만들었던건 관례로 굳어지게 되었는데 개발은 transaction script 형식으로 진행하다보니 관례는 관례대로 남고 애초에 그렇게 하고자했던 이유는 사라져버리게 된 것이다.
만약, 한 메서드에서 모든 역할을 다하는 절차지향적 코딩에서는 굳이 Service를 인터페이스로 만들 필요는 없다는 것이다.
물론 인터페이스를 만들 이유를 잘 살리는게 바람직한 방법이다.