인터페이스와 구현체에 대한 생각
JPA는 자바 진영에서 ORM(Object-Relational Mapping)의 기술 표준으로 사용하는 인터페이스의 모음이다. 즉,
JPA는 인터페이스이므로 이를 구현하는 실제 클래스가 필요하다
처음 "JPA는 인터페이스 이므로 이를 구현하는 실제 클래스가 필요하다"는 말이 잘 이해가 되지 않았다. ORM이라고는 Typescript에서 typeORM을 써본 경험밖에 없었다. 그래서 chatGPT에게 JPA를 사용하는 CRUD 예시코드를 부탁했다.
하이버네이트와 이클립스링크를 활용한 JPA CRUD를 보고 나니, 주요 로직 및 코드 구조가 차이가 없었다. 차이라곤 의존성 파일에 Hibernate를 추가하느냐, 이클립스링크를 추가하느냐 정도였다.
코드가 동일하지만, 내부 동작은 다를 수 있음. 그 내부 동작의 다름 여부가 사용자 입장에선 상관없음. 내 생각엔 다형성의 예시였다. 인터페이스 자체가 객체 지향 프로그래밍에서 추상화를 통한 "다형성"을 지원하기 위한 개념이었다.
이전에 나는 인터페이스란 그저 "중계자" 역할을 해 일정한 인풋에 따른 일관된 출력을 보장한다고만 생각했다. "일정한 입력에 대한 일관된 출력을 보장하는 것"은 인터페이스의 역할이다. 인터페이스를 사용해 특정한 동작 및 기능을 가진 클래스가 반드시 제공해야 하는 메서드를 정의하는 데 사용할 수 있다. -> 그렇기에 인터페이스는 하나 이상의 추상 메서드를 선언한다.
인터페이스는 "일정한 입력에 대한 일관된 출력을 보장"하므로 객체지향 프로그래밍에서 다형성과 유연성 증가에 도움을 준다. 인터페이스를 사용하는 것은 다음과 같은 이점이 있다.
1. 다형성 제공
2. 추상화와 모듈화 : 객체의 핵심기능을 정의하되, 내부 구현 세부사항은 캡슐화 할수 있다.-> 모듈화를 촉진한다.
3. 유연한 설계와 확장성 : 구현 세부는 다른 객체에게 자율적으로 맡길 수 있기에 객체간의 관계가 유연해지므로 유연한 설계가 가능하다.
4. 클래스(or 객체)간 결합도 낮춤 : 객체 간의 의존성이 줄어든다.
5. 다양한 구현체 지원 : 코드의 재사용성 증가, 새로운 구현체 적용이 쉬워진다. -> 다형성과 같은 이야기
6. 테스트 용이성 : 인터페이스를 사용해 모의 객체(Mock Object)를 이용한 테스트를 쉽게 수행할 수 있다.
JPA의 다양한 구현체 비교
그렇다면, JPA를 구현한 여러 ORM 프레임워크들을 대조 비교 해보자. 각각의 구현체들은 프로젝트의 요구 사항, 개발자의 경험, 성능 및 확장성을 고려해 선택하는데, 주로 Hibernate가 널리 사용되고 있다.
Hibernate | EclipseLink | DataNucleus | OpenJPA | |
특징 | - 강력한 기능 제공, 성숙한 생태계 및 커뮤니티- 다양한 데이터베이스와의 호환성- 성능 최적화 기능 | - 성능 최적화 관련 다양한 기능 제공- MOXy를 통한 JAXB 지원을 포함해 다양한 기능 | - JPA와 JDO(Java Data Objects)를 모두 지원- 다양한 데이터베이스와의 호환성- RDBMS외 NoSQL 데이터베이스와의 통합도 가능 | - 다양한 데이터베이스와의 호환성- 성능 최적화 관련 몇가지 기능 지원- IBM에서 기부한 Kodo와 Apache OpenJPA를 합쳐 개발됨 |
장점 | - 강력한 캐싱 전략 -> 성능 향상- 다양한 확장 기능과 도구 지원 | - JPA 표준에 대한 강력한 준수 보장- Eclipse IDE와 높은 통합성 제공- 성능 최적화에 중점을 둔 특징들이 있다 | - JPA, JDO, NoSQL 등 다양한 데이터 액세스 기술을 제공- 유연한 데이터베이스 지원과 확장성 | - 간단한 설정 및 사용 가능- 아파치 기반 프로젝트에서 사용하기 용이 |
단점 | - 학습 곡선이 다소 높다(익히고 습득하는데 어려움을 겪을 수 있다)- 초기 설정이 다양하고 복잡 | - Hibernate보다는 커뮤니티 규모가 작을 수 있다 | - 사용자 수가 적다 | - 커뮤니티 크기가 작다 |
JPA 표준을 엄격하게 준수할 수록 다른 JPA 구현체로의 전환성을 높이고, 표준 기능을 적용하는 데 도움이 된다.
참고문헌 : 점프투 스프링부트, ChatGPT