자바에는 abstract 클래스를 이용한 상속과 interface를 이용한 상속이 있습니다.
저는 interface로 기본 틀을 만들어 같은 기능을 하는 클래스에 다른 로직을 적용해야 할 때 많이 사용하고 있습니다.
스프링에서 Service 기능을 만들 때 UserServiceImpl, SettingServiceImpl 이런 구현체들을 많이 보셨을겁니다.
그러다가 전에 스프링부트로 개인프로젝트를 진행하면서 문뜩 생각이 났습니다.
"어쩌피 서비스 하나 구현해서 쓸건데 왜 굳이 인터페이스를 구현하고 정의해서 쓰지?"
UserService라는 interface를 만들고 UserServiceImpl 이라는 클래스를 하나 구현할건데 처음부터 클래스명을 UserService라고 하고 거기에 구현하면 되지 않을까 싶었습니다.
그래서 주변 시니어 개발자분에게 여쭤봤습니다. 돌아오는 대답은
"그냥 옛날부터 그렇게 썼으니까 쓰는게 좋지 않을까?"
사실 제가 여쭤봤던 개발자분은 금융 SI 업계에 종사하시는 개발자분이셨고, 오랜 기간동안 레거시한 프로젝트만 전문적으로 하셨던 분이셔서 옛날부터 줄곧 그렇게 쓰셨다고 합니다.
프로그램 구조가 바뀌기 힘든 금융권은 옛날부터 전자정부프레임워크 사용으로 인해 그 패턴이 계속 이어져 내려온 것인거죠.
개인적인 생각이지만 이렇게 Impl로 구현하는 것은 interface/implement 취지에도 맞지 않습니다.
위 구조를 보시면 Animal이라는 인터페이스를 만들고 구현할 때 우리는 그 인터페이스 속성을 가진 구현된 새로운 이름으로 Dog와 Cat클래스를 정의합니다. 일반적인 구조입니다. 구현한 클래스가 두개 이상이라 이름이 다를 수 있지 않냐 하실 수도 있습니다.
그럼, 위에서 설명한 UserService 같은 경우는 구현하는 내용이 두개 이상인가요? 어떤 구조를 사용하냐에 따라 다르겠지만 보통은 한개입니다.
만약 User의 서비스를 일반유저와 관리자로 분리를 한다면 UserService Interface를 만들고 UserServiceImpl/UserAdminServiceImpl 이런식으로 구현을 할 수도 있겠지만 보통 Spring Security에서는 Controller에서 권한을 설정하기 때문에 서비스는 하나만 구현합니다.
또 다른 예시로 이런 것도 생각할 수 있습니다.
우리가 흔히 쓰는 ArrayList와 LinkedList는 List를 구현하고 있습니다. 이 구현체들이 Impl이라는 키워드를 가지고 있나요?
결론은 쓸데없는 파일이 하나가 더 생긴다는 겁니다.
저는 그냥 이 패턴이 싫었습니다. 그래서 회사에서 새로 만드는 프로젝트나 리팩토링을 할 때 Side Effect를 감수하고 과감히 Service 인터페이스를 제거하고 구현체들을 모두 클래스화 했습니다.
패턴을 바꾸니 이제 IDE에서 메소드의 구현체를 찾아가야 할 때 인터페이스를 거치지 않고 바로 구현해둔 클래스로 접근할 수 있었습니다. 구현체로 바로가는 단축키도 있지만 저는 컨트롤을 누르고 메서드명을 눌러서 이동해 사용을 했었고요 (저는 이게 편해서..)
쓸데없는 파일도 없어져서 파일 리스트에서 가독성도 꽤 좋아졌다고 생각합니다.
첫 포스팅이고 아직 주니어 개발자라 내용을 정리하는데 누락되거나 미숙한 부분들이 있습니다.
제 주관적인 생각을 적어본거라 100% 맞다고는 할 수 없습니다.
다른 의견 있으신 분께서는 댓글로 피드백 주시면 감사하겠습니다.
참고: https://octoperf.com/blog/2016/10/27/impl-classes-are-evil/
'Spring' 카테고리의 다른 글
[JPA] ORM #1 (0) | 2023.02.19 |
---|---|
Jackson에서 Boolean 직렬화 시 is가 사라지는 문제 (0) | 2022.03.12 |