Controller - entity - Service - Repository 는 일종의 패턴 같은 것인데 큰 틀로는 아래와 같다.
- Client 가 Request 를 보낸다.
- Request URL에 알맞은 Controller 가 수신한다.
- Controller 는 넘어온 요청을 처리하기 위해 Service 를 호출한다.
- Service 는 알맞은 정보를 Repository 에서 가져온 후 가공하여 Controller 에게 데이터를 넘긴다.
- Controller 는 Service 의 결과물을 Client 에게 전달해준다.
여기서 service 가 client 의 요청에 대한 올바른 정보를 제공하기 위한 것을 '비즈니스 로직을 수행한다'고 말한다. 만약 service 를 거치지 않고 controller 에서 repository 에 접근하는 방식으로 사용한다면 어떻게 될까? controller - entity - repository 의 깔끔한 형태가 될 것이다. 하지만 이런 방식의 코드는 좋은 코드가 아니다.
프레젠테이션 계층, 즉 controller 에서 비즈니스 로직을 명시하는 것은 좋지 않다. 비즈니스 로직은 다른 요청 URL 에서 사용해야 하는 경우가 있는데 만약 비즈니스 로직 코드가 컨트롤러에 구현되어 있는 경우, 다른 컨트롤러의 메서드에서 똑같은 로직 코드를 구현해야 한다. 결국 중복 코드가 발생하고 재사용성이 줄어든다.
그리고 만약 이 로직이 굉장히 복잡하고 긴 코드로 되어있다고 가정하면, 이 비즈니스 로직을 필요로 하는 다른 요청이 있는 경우 그것을 다시 controller 에서 작성해주어야 한다. 하지만 이 로직을 service 계층으로 분리하게 되면 service 에서 해당 비즈니스 로직을 가져다 사용하면 되기 때문에 코드를 중복으로 작성할 필요 없이 재사용이 가능하다.
스프링 부트에서 Controller, Service, Repository 를 생성하는 도중 서비스 클래스의 역할은 무엇일까? 라는 생각이 들었다. 레포지토리에서 바로 컨트롤러로 넘겨주면 안될까? 아니면 컨트롤러 자체에서 구현하면 안되나? 강의에서도 서비스를 중간 다리로 사용해서 컨트롤러에게 데이터를 넘겨준 것을 보긴 했지만 사실 명확하게 서비스가 필요한 이유는 생각해보지 않았어서 정리해 본 글이다.
그리고 애초에 컨트롤러는 클라이언트에게 뷰를 보여주는 역할이고, 레포지토리는 저장소인데 리퀘스트 요청을 처리하는 로직을 구현한다는 것 자체가 말이 안된다. 저장소가 스스로 데이터를 수정하고 데이터를 호출하며 사용한다는 것이 논리적으로 맞지 않는 것이다. 만약 레포지토리에서 바로 컨트롤러로 넘겨주는 로직을 구현했을 때, 만약 추후 레포지토리 클래스가 외부 DB를 사용하는 것으로 바뀌었을 때는? 그러면 그 로직을 책임 질 객체가 다시 필요하게 된다. 처음부터 관심사의 분리로 각각의 단일 책임을 가진 객체를 만들어놔야 한다.
'TIL' 카테고리의 다른 글
JavaScript - destructuring, rest (22.10.17 TIL) (0) | 2022.10.17 |
---|---|
수고했다 오늘도! (22.10.14 TIL) (0) | 2022.10.14 |
피하지 말고 즐기자! (22.10.12 TIL) (0) | 2022.10.12 |
POJO vs Java Beans (22.10.11 TIL) (0) | 2022.10.11 |
POJO (22.10.10 TIL) (0) | 2022.10.10 |
댓글