Getter Setter를 사용하는 이유
- 객체의 무결성을 보장하기 위해
- 예를 들어, 만약 외부에서 몸무게라는 필드에 직접 접근한다면 0보다 낮은 값을 줄 수도 있다. 이 경우 객체의 무결성이 깨지기 때문에 이를 방지하기 위해 Getter/Setter를 사용하여 데이터의 무결성을 지켜준다.
🤔 무결성이란 무엇인가?
데이터의 정확성과 일관성을 유지하고 보증하는 것을 말한다.
🤔 Getter/Setter를 사용하면 데이터 무결성이 지켜지는가?
Getter, Setter를 이용해서 데이터를 생성 및 접근을 하게 되면 들어오는 값을 바로 저장하는 게 아닌,
한번 검증하고 처리할 수 있도록 할 수 있기 때문에 데이터의 무결성이 지켜진다.
- Getter : 본 필드의 값을 숨긴 채 내부에서 가공된 값을 꺼낼 수 있다.
- Setter : 필드를 private로 만들어 외부의 접근을 제한한 후, Setter를 사용해 전달받은 값을 내부에서 가공해 필드에 넣어줄 수 있다.
🤔 Getter/Setter를 사용할 때의 다른 이점
- Getter, Setter와 같은 엑세스 함수 사용 시, 위와 같은 데이터 무결성과 유효성 검사 가능
- 객체의 필드를 private과 같은 접근제한자를 두면서 정보은닉 가능
getter setter에 대한 피드백
- Setter를 데이터 무결성과 연결하시면 면접관들이 읭?하실 가능성이 있다. Setter보다는 Builder 패턴이나 SOLID 개방폐쇄원칙에 더 적합한 주제이다.
단순히 setter로 데이터를 수정하면, 어떤 부분을 수정하는지, 어디서 데이터를 수정하는지 알 수 없다
이러한 부분을 해결하기위해 Builder 패턴이라는 것을 사용하는데
Builder 패턴이란
복잡한 객체를 생성하는 방법을 정의하는 클래스와 표현하는 방법을 정의하는 클래스를 별도로 분리하여, 서로 다른 표현이라도 이를 생성할 수 있는 동일한 절차를 제공하는 패턴이다.
class Team {
private String name;
private int playCount;
private int victoryPoint;
private int winCount;
private int drawCount;
private int loseCount;
private int scorePoint;
public static Builder builder() {
return new Builder();
}
public static class Builder {
private String name;
private int playCount;
private int victoryPoint;
private int winCount;
private int drawCount;
private int loseCount;
private int scorePoint;
private Builder() {
}
public Builder name(String name) {
this.name = name;
return this;
}
public Builder playCount(int playCount) {
this.playCount = playCount;
return this;
}
public Builder victoryPoint(int victoryPoint) {
this.victoryPoint = victoryPoint;
return this;
}
public Builder winCount(int winCount) {
this.winCount = winCount;
return this;
}
public Builder drawCount(int drawCount) {
this.drawCount = drawCount;
return this;
}
public Builder loseCount(int loseCount) {
this.loseCount = loseCount;
return this;
}
public Builder scorePoint(int scorePoint) {
this.scorePoint = scorePoint;
return this;
}
public Team build() {
Team team = new Team();
team.name = this.name;
team.playCount = this.playCount;
team.victoryPoint = this.victoryPoint;
team.winCount = this.winCount;
team.drawCount = this.drawCount;
team.loseCount = this.loseCount;
team.scorePoint = this.scorePoint;
return team;
}
}
}
Team team = Team.builder()
.name("맨유")
.playCount(3)
.victoryPoint(6)
.winCount(2)
.drawCount(0)
.loseCount(1)
.scorePoint(4)
.build();
Spring에서는 이 builder패턴을 지원하는 어노테이션이 존재한다.
public static class SignUpReq {
private com.cheese.springjpa.Account.model.Email email;
private Address address;
@Builder
public SignUpReq(Email email, String fistName, String lastName, String password, Address address) {
this.email = email;
this.address = address;
}
public Account toEntity() {
return Account.builder()
.email(this.email)
.address(this.address)
.build();
}
}
public Account create(AccountDto.SignUpReq dto) {
return accountRepository.save(dto.toEntity());
결론
Getter와 Setter를 사용하는 이유는, 데이터를 보호하기 위함이다.
데이터를 불러올 때, 한번 더 가공하는 과정을 거침으로써, 내부 데이터가 결함을 가지지 않도록 하는 것이다.(무결성)
단, 무분별한 Setter는 데이터 무결성을 해칠 수 있다.
이를 해결하기위해, 객체를 생성하는 생성자와, 이를 표현하는 메소드를 분리하여 사용하는 Builder 패턴을 이용해서 데이터 조금 더 직관적인 코드를 작성할 수 있다.
'Spring' 카테고리의 다른 글
트랜잭션 전파 (기본, 내부, 외부) (0) | 2023.07.27 |
---|---|
트랜잭션 commit, rollback (0) | 2023.07.24 |
트랜잭션 AOP 주의 사항 - 프록시 내부 호출 (0) | 2023.07.18 |
JPA (0) | 2023.07.12 |
[JUnit5] 기본 Annotation (0) | 2023.07.11 |