[Refactoring] 냄새 22. 데이터 클래스
14 Jan 2023해당 포스트는 inflearn의 백기선님의 강의인 리팩토링 을 듣고 정리한 글입니다.
냄새 22. 데이터 클래스
- 데이터 클래스 : public 필드 또는 필드에 대한 게터와 세어만 있는 클래스 (DTO)
- 코드가 적절한 위치에 있지 않기 때문에 이러한 냄새가 생길 수 있다.
- 예외적으로 “단계 쪼개기”에서 중간 데이터를 표현하는데 사용할 레코드는 불변 객체로 데이터를 전달 하는 용도로 사용할 수 있다.
- public 필드를 가지고 있다면 “레코드 캡슐화 하기 (Encapsulate Record)“를 사용해 게터나 세터를 통해서 접근하도록 고칠 수 있다.
- 변경되지 않아야 할 필드에는 “세터 제거하기 (Remove Setting Method)”를 적용할 수 있다.
- 게터와 세터가 사용되는 메소드를 찾아보고 “함수 옮기기(Move Function)”을 사용해서 데이터 클래스로 옮길 수 있다.
- 메소드 전체가 아니라 일부 코드만 옮겨야 한다면 “함수 추출하기(Extract Function)”을 선행 후에 옮길 수 있다.
리팩토링 42. 레코드 캡슐화 하기
- 변하는 데이터를 다룰 때는 레코드 보다는 객체를 선호한다.
- 여기서 “레코드”란, public 필드로 구성된 데이터 클래스를 말함.
- 데이터를 메소드 뒤로 감추면 객체의 클라이언트는 어떤 데이터가 저장되어 있는지 신경쓸 필요가 없다.
- 필드 이름을 변경할 때 점진적으로 변경할 수 있다.
- 하지만 자바의 Record는 불변 객체라서 이런 리팩토링이 필요없다.
- public 필드를 사용하는 코드를 private 필드와 게터, 세터를 사용하도록 제한한다.
아래의 코드는 조직의 정보를 가진 데이터 클래스지만 name
, country
필드가 public으로 되어있어서 외부에서 호출이 가능하다.
- Organization
public class Organization {
public String name;
public String country;
}
아래와 같이 getter나 setter가 아닌 필드의 호출을 통해 외부에서 변경이 가능하다.
class OrganizationTest {
@Test
void name() {
Organization organization = new Organization();
organization.name = "mho";
}
}
보통은 private필드로 변경하여 getter, setter를 만들것이다.
하지만 해당 데이터가 불변으로 변경되지 말아야 한다면 record 를 사용할 수 있다.
record는 JAVA 14에서 추가된 기능으로 불변 필드를 가진 객체를 가진다.
public record OrganizationRecord(String name, String country) {
}
이렇게 name, country필드를 가진 record를 생성한다면 내부에서 자체적으로 final로 선언을 하였기 때문에 선언을 한 이후에 아래와 같이 값을 변경하는 것이 불가능하다.
- 불가능한 예시 (컴파일 하기도 전에 IDE에서 에러로 잡힌다.)
public record OrganizationRecord(String name, String country) {
public void setName(String word) {
this.name = word;
}
}
class OrganizationTest {
@Test
void name() {
OrganizationRecord organization = new OrganizationRecord("mho", "Korea");
organization.setName("mho");
}
}