언제 어떤 곳에서든 인스턴트 객체의 데이터를 수정할 수 있다면, 추후 데이터의 값에 오류가 생겼을 때 언제 어디서 잘못되었는지 알 수 없다. 즉, 엔터티 클래스에서 Setter를 두는 것은 데이터 무결성에 상당한 위협이 된다.
현재 프로젝트의 회원 엔터티에는 임시로 Setter를 두었는데 이번에 서비스 로직을 구현하면서 해당 부분을 같이 리팩토링해주었다.
하지만 사실 Setter를 두면 안 된다는 사실만 알고 있었지, 구체적으로 어떻게 해결해야 하는지 몰랐다.
그래서 검색해보니 주로 사용하는 방법은
첫째로 객체 초기화는 생성자를 통해서 최초에만 데이터를 주입하고,
둘째로 수정 필요시 메서드로써 논리적인 기능을 통해서만 수정해주는 것이었다.
ex) //상품 재고 수량 증가
public static void addStock(int addQuantity){
stocks += addQuantity;
}
//상품 재고 수량 감소
public static void removeStock(int rmQuantity){
stocks -= rmQuantity;
}
이렇게 되면 임의로 데이터 값을 수정할 수 없으니 위에서 언급한 문제(데이터 오류의 원인을 알 수 없는 문제)가 바로 해결됨을 알 수 있을 것이다.
또한 해당 객체에 대한 논리적 로직을 해당 객체의 멤버 Function을 통해 실행하므로 코드의 응집력을 높여주는 진정한 객체지향 설계이자 도메인 주도 설계의 파워를 실감할 수 있었다.
위의 작업에 있어서 편리한 기능을 제공하는 Lombok 어노테이션을 많은 사람들이 활용하고 있다는 걸 알게 됐다.
이 어노테이션의 사용 방법은 사실 다음 예시와 같이 굉장히 간단해서 코드만 봐도 어떻게 쓰는지 바로 알 수 있다.
@Builder
class Member{
private String name;
private int age;
private String address;
}
class Main{
public static void main(String[] args){
Member newMember = Member.builder()
.name("Lee")
.age(25)
.address("Busan")
.build();
}
}
보다시피 생성자 파라미터에 나열하지 않아도 되어 가독성도 좋아지는 효과까지 있다.
우리 프로젝트에는 회원 엔터티와 장애인, 사회복지사, 일반 회원이 상속관계에 있는데 이 경우에는 @Builder를 사용하니 자식 클래스의 데이터 멤버에 접근할 수 없었다.
그래서 찾아보니 역시나 이 상속관계를 대비한 방법도 존재했다. 이 때는 @Builder 대신 @SuperBuilder를 부모, 자식 클래스 모두에 사용해주면 되었다.