@Setter
사용 시 메서드명은 setXxx()
가 될 것이다.
이러한 메서드명은 어떤 의도로 이 메서드를 사용한 건지 파악을 하기 매우 어렵다.
-> 의도를 파악하기 쉽게 메서드명을 설정해야 한다.
예를 들어 분실물의 발견 여부를 체크하는 필드가 있다고 가정해 보자.
public class Item {
public void foundItem() {
this.found = true;
}
}
public void 분실물_발견됨() {
item.foundItem();
}
이런식으로 단순히 setter를 사용하는 것보다 의도를 정확하게 드러내는 것이 중요하다.
@Setter
를 클래스 단위에 붙여두면 막 변경하면 안되는 필드에도 setter 메서드가 만들어 진다.
이렇게 되면 다른 개발자가 그냥 이 메서드를 사용해 버릴 수 있다.
-> 변경이 필요하지 않는 필드는 setter 메서드를 만들면 안된다. 다른 개발자도 변경할 수 있는 메서드가 없는 것을 보고 "아 이 필드는 막 변경해서는 안되는 필드구나."라고 생각할 것이다.
예를 들어 다음과 같이 @Setter
를 사용한 회원 엔티티 클래스가 있다고 가정해 보자.
@Getter @Setter
@Entity
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(unique = true)
private String username;
private String password;
}
이제 회원 로직은 다 개발된 상태에서 이메일 필드를 추가하고자 한다.
그럼 회원가입, 회원 정보 수정 등 여러 곳에서 유지보수 작업을 해야 한다.
프로젝트가 매우 클 경우 해야 될 작업이 너무 많아 개발자가 어디를 수정해야 하는 지조차 찾기 힘들며 일일이 수정하기 너무 번거롭다.
-> 생성자나 빌더 패턴을 사용하자.
그럼 setter 메서드를 사용하지 않으면 DB에는 어떻게 반영하는거지?
다음 예제를 보자.
@Getter
@Entity
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(unique = true)
private String username;
private String password;
@Column(unique = true)
private String email
public Member(String username, String password, String email) {
this.username = username;
this.password = password;
this.email = email;
}
}
@Setter
를 사용하지 않고 생성자 를 사용하였으며, email 필드를 추가하였다.Member member = new Member("user", "abc123");
memberRepository.save(member);
이제 위와 같은 기존 로직에서 바로 오류 표시가 뜰 것이다. 그럼 다음과 같이 email
을 추가해 주면 된다.
Member member = new Member("user", "abc123", "abc@abc.com");
memberRepository.save(member);
setter 메서드를 사용했다면 오류 위치가 바로 뜨지 않아 찾기 번거로웠을 것이며, 필드마다 setter를 사용해야 하므로 코드가 더 길었을 것이다.
하지만 생성자를 사용한 방식에도 문제점이 존재한다.
파라미터 위치가 정확해야 하는데 이게 어떤 필드랑 매칭이 되는지 직접 엔티티 클래스에 들어가서 확인해보아야 하고.. 굉장히 번거롭다.
Member member = new Member("abc123", "user", "abc@abc.com");
memberRepository.save(member);
위와 같이 username
과 password
위치를 반대로 적었다고 가정해 보자. 그럼 실행하기 전까지 문제를 발견할 수 없다.
현재는 파라미터가 적기 때문에 별 문제 없을 거라 생각할 수 있지만 파라미터가 굉장히 많다면 실수하기도 쉽고 가독성도 매우 안좋을 것이다.
-> 빌더 패턴을 사용하면 이러한 문제를 해결할 수 있다.
@Getter
@Entity
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(unique = true)
private String username;
private String password;
@Column(unique = true)
private String email
@Builder
public Member(String username, String password, String email) {
this.username = username;
this.password = password;
this.email = email;
}
}
@Builder
를 적용하였다.Member member = Member.builder()
.username("user")
.password("abc123")
.email("abc@abc.com")
.build();