@Getter & @Setter 사용을 지양하세요.

Daniel·2023년 7월 11일
0

Back-End

목록 보기
20/42

지금까지는 DTO객체에는 @Data, VO객체에는 @Value 를 사용 @Getter 와 @Setter를 사용해왔다.
사실 그냥 그렇게 쓰고있고, 쓰라니깐 클래스를 만들면 무지성 으로 어노테이션을 붙였던게 아닌가 하는 생각에 공부 및 정리겸 이 포스트를 작성합니다.

왜 지양해야해?

객체지향적인 설계 원칙과는 어긋납니다.

@Getter 및 @Setter 어노테이션은 객체의 상태를 직접적으로 변경하는 방식으로 작동하며, 이는 캡슐화 및 정보 은닉을 위반할 수 있습니다.
이에 따라, 개발자들은 직접적인 상태 변경 대신 객체의 메소드를 사용하거나 불변성 객체를 사용해 좀 더 객체지향적인 설계 원칙에 가깝게 코드를 짤 수 있습니다.

간단한 예제


@Getter
@Setter
public class Person{
	private String 이름;
	private int 나이;
	privare String 주민번호앞자리;
}

위 Person 객체를 보면 @Getter 와 @Setter 붙은 클래스이며 3가지의 상태(필드)를 가지고 있다.

발생가능한 문제점

@Getter 와 @Setter가 붙음으로 인해 외부의 객체들이 Person 객체 의 상태에 접근해 이리저리 조작 및 조회 가 가능하다.
즉, 다른 외부 객체에서도 접근이 가능하며 private 키워드 조차 필요 없어지고 자기자신의 상태가 외부객체에 따라 달라질 수 있으니, 캡슐화한 의미가 없어진다.

다른 사람이 코드를 보거나, 보거나, 나중에 본인이 짠 코드를 봤을 때, 값을 변경한 의도를 파악하기 어렵다.
즉, 코드를 역추적해봐야 한다. 값을 넣어야할 필드가 많아지면 무분별하게 setter가 나열된다. setter를 나열하기만 하면 어떤 의도로 데이터를 변경한 것인지 명확하지 않다.

객체의 일관성이 떨어진다. setter로 값을 변경할 수 있다면 모든 곳에서 객체 값의 변경이 가능한데, 객체의 값을 변경하는 메소드가 의미가 왜 필요하겠는가. 또 setter 때문에 의도치 않게 값이 변경될 수 없는 위험이 존재하므로 사전 차단해야 한다.

Tell, Don't Ask (묻지말고 달라해...!!)

public class Person{
	private String 이름;
	private int 나이;
	privare String 주민번호앞자리;
	
	public Person(String 이름, int 나이, String 주민번호앞자리) {
		this.이름 = 이름;
		this.나이 = 나이;
		this.주민번호앞자리 = 주민번호앞자리;
	}
	public String get이름() {
		return 이름;
	}
	public int get나이() {
		return 나이;
	}
	public int get주민번호앞자리() {
		return 주민번호앞자리;
	}
	public void celebrateBirthday() {
		나이++;
	}
}

생성자를 사용해 값들을 초기화 한 후, 외부에서 필요한 정보 및 기능만 공개

지양이 곧 손절은 아닙니다!

상황에 맞추어 필요한 상황에 적절히 사용하는게 조금더 나은 개발자가 되는 길인 것 같습니다.

  1. 데이터 전송 객체 (DTO) 및 값 객체 (VO) 클래스
    DTO 및 VO 클래스는 주로 데이터를 저장하고 전달하는 데 사용됩니다. 이러한 클래스에서는 일반적으로 상태가 노출되기 때문에, @Getter 및 @Setter를 사용하여 코드를 간결하게 작성할 수 있습니다.

  2. 자동 생성 메소드 (Builder)
    Builder 패턴에서는 @Getter 및 @Setter를 사용하여 객체의 속성에 액세스하고 변경할 수 있습니다. 이 패턴은 객체 생성 및 초기화를 단순화하는 데 유용합니다.

profile
응애 나 애기 개발자

0개의 댓글