-
Spring Boot - Service와 ServiceImpl 구조Framework & Library/Spring Boot 2023. 2. 5. 17:06
Service와 ServiceImpl 구조
Service와 ServiceImpl 구조를 사용하는 이유
대부분의 프로젝트는 Service 클래스를 만들 때 MemberService와 같은 인터페이스를 설계한 후 MemberServiceImpl이라는 구현체 클래스를 생성해서 사용하는 방식으로 설계된다.
위와 같은 Service와 ServiceImpl을 구분해서 설계하는 이유는 인터페이스와 구현체를 분리함으로써 구현체를 독립적으로 확장할 수 있으며, 구현체 클래스를 변경하거나 확장해도 이를 사용하는 클라이언트의 코드에 영향을 주지 않도록 하기 위함이다.
이 같은 추상화를 통한 구현 방식은 객체지향 특징 중 하나인 다형성과 객체지향의 다섯 가지 원칙 중 하나인 OCP 원칙을 가장 잘 실현해 주는 설계 방식이다.
※ 다형성 : 하나의 객체가 여러 가지 타입을 가질 수 있는 것을 의미
※ OCP 원칙 : 기존의 코드를 변경하지 않으면서, 기능을 추가할 수 있도록 설계가 되어야 한다는 원칙
하지만, 실제로 대부분의 프로젝트에서는 인터페이스와 구현체 클래스 사이의 관계가 1:1 관계로 구성되어 있기 때문에, 인터페이스와 클래스 구조를 사용하는 것에 대한 이점을 전혀 가지지 못한다.
Service와 ServiceImpl 구조의 사용
MainService 인터페이스 구현
public interface MainService { ResponseEntity<?> doAction(); }
MainService 인터페이스이다. doAction() 기능을 정의한다.
MainServiceImplA 클래스 구현
@Service public class MainServiceImplA implements MainService { @Override public ResponseEntity<?> doAction() { System.out.println("Do Action A"); } }
MainServiceImplA 클래스에서 doAction() 기능을 구현한다.
MainServiceImplA 클래스의 사용
@Controller public class MainController { @Autowired private MainService mainService = new MainService(); @GetMappin("/main") public void doAction() { mainService.doAction(); // MainServiceImplA 클래스의 doAction() 메서드 실행 } }
Controller 단에서 MainServiceImplA 클래스에서 구현한 로직을 사용하기 위해서는 위와 같이 사용이 가능하다.
MainServiceImplB 클래스의 구현
@Service public class MainServiceImplB implements MainService { @Override public ResponseEntity<?> doAction() { System.out.println("Do Action B"); } }
MainServiceImplA 클래스의 doAction() 기능을 사용하고 있는 상황에서, 새로운 doAction() 기능으로 교체해야 하는 상황이 발생하여, 새로운 MainServiceImplB 클래스에서 doAction() 기능을 구현하였다.
MainServiceImplB 클래스의 사용
@Controller public class MainController { @Autowired private MainService mainService = new MainService(); @GetMappin("/main") public void doAction() { mainService.doAction(); // MainServiceImplB 클래스의 doAction() 메서드 실행 } }
새롭게 추가된 요구사항인 MainServiceImplB 클래스의 doAction() 기능으로 교체하기 위해서는 단순히 MainSerciceImplA 클래스의 @Service 애너테이션만 삭제해 주면 된다.
이렇게, 기능을 추상화하는 인터페이스와 실제 구현체인 클래스 구조를 사용한다면, 코드의 수정과 확장이 용이하다.
출처
ㆍ https://wildeveloperetrain.tistory.com/49#recentEntries
728x90'Framework & Library > Spring Boot' 카테고리의 다른 글
Spring Boot - @PathVariable & @RequestParam & @ModelAttribute (0) 2023.02.06 Spring Boot - DI(Dependency Injection)의 세 가지 방법 (0) 2023.02.05 Spring Boot - DTO & VO & Entity (0) 2023.02.04 Spring Boot - JavaMailSender를 활용하여 메일 전송하기 (0) 2023.01.31 Spring Boot - HandlerMapping의 동작 방식 (0) 2023.01.30