
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "member")
@Entity(name = "Member")
쓸데없는 entity 관련 어노테이션이 너무 많다.
각 어노테이션의 기능을 정리하고 불필요한 것을 제거해보자.
Entity를 작성할 때 @Setter 어노테이션을 사용하면 편리한 것은 사실이다.
비즈니스 로직에서 아래와 같은 방법으로 객체의 값을 쉽게 변경할 수 있기 때문.
member.setName("홍길동");
그러나 조금만 찾아보면 @Setter를 지양해야 함을 알 수 있다.
이유가 뭘까?
@Setter를 사용하면 객체 외부에서 무분별하게 객체의 값을 변경하게 될 수 있다.
이것은 객체의 무결성과 불변성에 큰 위협이 된다.
또한 @Setter는 사용의 의도를 알기가 어렵다는 단점이 존재한다.
이러한 이유로 @Setter 대신 빌더 패턴을 사용하는 개발자들이 많다.
하지만 @Builder의 단점도 존재한다.
나는 개인적으로 @Builder를 선호하지 않는다.
객체의 필드가 많아질 경우 코드가 길어지고, 코드의 중복이 심해지기 때문에 유지보수가 어렵다.
예를 들어 @Builder를 사용하면 다음과 같은 코드를 작성해야한다.
public String createMember(MemberDto memberDto) {
Member member = Member.builder()
.id(memberDto.getId())
.password(memberDto.getPassword())
.name(memberDto.getName())
.phone(memberDto.getPhone())
.college(memberDto.getCollege())
.department(memberDto.getDepartment())
.major(memberDto.getMajor())
.privacy(memberDto.isPrivacy())
.build();
return memberRepository.save(member).getId();
}
위 코드는 새로운 member 정보를 받아서 DB에 저장하는 BL이다.
@Builder 패턴 때문에 코드가 길어지게 되었고, 다른 메서드에서도 member를 저장할 경우에 저렇게 긴 코드가 여러번 중복될 것이다.
만약 member 객체의 필드를 추가하거나 제거한다고 생각하면 끔찍하다.
lombok 어노테이션 중에 이미 @Builder의 역할을 하고 있는 것이 있다.
바로 @AllArgsConstructor가 전체 필드에 대한 생성자 이므로 그냥 이걸 쓰면 된다.
public static Member of(String id, MemberDto memberDto) {
return Member.of(
id,
memberDto.getPassword(),
memberDto.getName(),
memberDto.getPhone(),
memberDto.getAge(),
true,
Role.valueOf(memberDto.getRole()),
Grade.valueOf(memberDto.getGrade()),
College.valueOf(memberDto.getCollege()),
.... );
}
@NoArgsConstructor는 기본 생성자를 만들어주는 lombok 어노테이션이다.
그런데 대부분의 코드에서 access = AccessLevel.PROTECTED 가 함께 사용된 것을 볼 수 있는데,
접근 지정자를 걸어 무분별한 객체 생성을 막아주는 역할을 한다.
단 JPA는 protected를 제한 할 수 있는 최대한의 접근 지정자로 받아들인다.
@Getter
@Table(name = "member")
@Entity(name = "Member")
@AllArgsConstructor(staticName = "of")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Member {
}