JPA 엔티티 생성시 setter 메서드를 지양해야 하는 이유는 객체 지향 프로그래밍의 원칙 중 하나인 캡슐화와 깊은 관련이 있습니다.
JPA 엔티티는 데이터베이스 테이블과 매핑되는 객체로, 데이터의 상태와 비즈니스 로직을 담습니다. 엔티티에서 setter를 무분별하게 사용하는 것은 다음과 같은 문제를 초래할 수 있습니다.
- 캡슐화 원칙 위반
setter 메서드를 통해 엔티티의 상태를 쉽게 변경할 수 있게 하면, 객체의 내부 상태가 외부에서 쉽게 조작될 수 있습니다. 이렇게 되면 엔티티의 데이터 무결성을 유지하기가 어렵고, 예기치 않은 상태 변경이 발생할 수 있습니다. 엔티티의 데이터를 수정할 때는 반드시 해당 수정이 비즈니스 로직에 부합하는지 확인해야 하는데, setter는 이러한 검증 과정을 우회합니다. - 불변성 위반
엔티티가 한 번 생성된 후에는 가능한 한 상태를 변경하지 않는 것이 좋습니다. 하지만 setter를 통해 언제든지 필드를 수정할 수 있다면, 엔티티는 불필요하게 변할 가능성이 커지며, 이로 인해 디버깅과 유지보수가 어려워집니다. - 프록시 객체 문제
JPA에서는 엔티티를 지연로딩하기 위해 프록시 객체를 생성할 수 있습니다. 이때 setter를 남용하면 프록시 객체의 일관성을 해칠 수 있으며, 이는 데이터베이스 상태와 메모리 상의 엔티티 상태가 불일치하는 문제를 일으킬 수 있습니다.
해결방안
더보기
생성자나 빌더 패턴 사용: 생성자를 통해 필수 필드만 설정하거나, 빌더 패턴을 사용해 생성 시점에 필요한 값을 설정하고 이후에는 상태 변경을 최소화하는 것이 좋습니다. 이렇게 하면 객체의 일관성과 무결성을 유지할 수 있습니다.
더불어, 서비스계층에서 Builder 패턴을 지양해야하는 이유
- 비즈니스 로직 분리 실패
서비스 계층은 비즈니스 로직을 처리하는 곳입니다. 만약 서비스 단에서 builder 패턴을 사용하면 비즈니스 로직이 엔티티의 생성 방식에 묶일 수 있어 코드의 응집도가 떨어집니다. 이는 서비스 계층이 객체 생성에 관여하는 것을 의미하며, 결과적으로 서비스 단에서 해야 할 일과 객체 생성이 혼재될 수 있습니다. 객체 생성은 보통 팩토리 패턴이나 별도의 빌더 클래스로 분리하는 것이 좋습니다. - 복잡성 증가
서비스 레이어는 주로 트랜잭션 관리, 비즈니스 규칙 처리 등의 역할을 담당합니다. 여기서 객체 생성 로직까지 처리하면 서비스 레이어의 책임이 불필요하게 복잡해질 수 있습니다. 따라서 객체 생성을 위한 로직은 도메인 모델이나 DTO 생성 부분으로 분리하는 것이 더 적합합니다.
캡슐화와의 관계
캡슐화는 객체 지향 설계의 핵심 원칙 중 하나로, 객체의 상태(데이터)를 외부에서 직접 접근하지 못하게 하고, 객체 내에서만 상태를 관리하도록 하는 원칙입니다. 이를 통해 객체의 일관성을 유지하고, 외부 코드와의 결합도를 낮출 수 있습니다.
- 엔티티의 상태 관리
JPA 엔티티에서 setter 메서드를 제거하고 필드 값을 직접 변경하지 못하게 하여 상태를 안전하게 보호할 수 있습니다. 이렇게 하면 엔티티의 필드가 외부에서 임의로 수정되는 것을 방지하여 엔티티의 일관성을 유지할 수 있습니다. - 책임의 분리
서비스 단에서 객체 생성 로직을 배제하고, 비즈니스 로직과 객체 생성의 책임을 분리하면 코드의 가독성 및 유지 보수성이 높아집니다. 이는 객체 지향 설계에서의 단일 책임 원칙(Single Responsibility Principle, SRP) 을 따르는 것과도 관련이 있습니다.
'개발관련' 카테고리의 다른 글
토스에서는 GATEWAY를 어떻게 활용할까? (2) | 2024.09.30 |
---|---|
Netfilx는 PassPort ? (1) | 2024.09.27 |
MSA 기반 물류관리 및 배송시스템 프로젝트를 마치며... (0) | 2024.09.24 |
Gateway 에 관하여 내가 프로젝트를 진행하면서 해야할것 (2) | 2024.09.13 |
[Spring Security] @EnableMethodSecurity와 @EnableGlobalMethodSecurity (0) | 2024.09.10 |