• 개요

    보통 자바 클래스는 자바빈 규약을 지키기 위해서 Getter/Setter를 명시하는 경우가 많습니다. 하지만 Setter를 무분별하게 사용하는 것은 문제가 발생할 여지가 있기 때문에 최근에는 Setter 사용을 지양하는 경우가 많습니다.

  • 사용지양 이유

    1. 의도를 알기 어려움

      public Person updatePersonInfo(Long id, PersonUpdateDto updateDto) {
        final Person person = findById(id);
      	person.setName(updateDto.getName);
      	person.setAddress(updateDto.getAddress);
      	person.setPhoneNumber(updateDto.getPhoneNumber);
      	return person;
      }
      

      위의 Setter만 본다면 그냥 값을 Setting 한다는 것만 알 수 있지 Person의 정보를 수정하기 위해 값을 다시 Setting 한다고 단번에 생각하기에는 힘듭니다. 어떤 변화를 주기 위해서 값을 변경하는지 명확한 의도를 나타내지 않는다.

      따라서 도메인 클래스에서 회원정보 수정이라는 update 메소드를 만들어 내부 로직으로 사용하고 Service와 같은 다른 Layer에서 update 메소드를 호출하는 방식이 훨씬 가독성이 올라가고 어떤 행위를 하고자 하는지 의도를 파악하기 쉽습니다.

      public class Person {
         private String name;
         private String address;
         private String phoneNumber;
      
         public void updatePersonInfo(PersonUpdateDto updateDto) {
      		 this.name = updateDto.getName;
      		 this.address = updateDto.getAddress;
      		 this.phoneNumber = updateDto.getPhoneNumber;
         }
      }
      
      public class PersonService {
      	public Person updatePersonInfo(Long id, PersonUpdateDto updateDto) {
      	  final Person person = findById(id);
      		// update 메소드 호출로 명확히 의도를 들어내고 가독성을 높임
      		person.updatePersonInfo(updateDto);
      		return person;
      	}
      }
      
    2. 일관성 유지에 어려움

      자바 빈 규약을 따르는 Setter는 public으로 어떤 곳에서도 접근이 가능합니다. 이렇게 되면 개발자도 결국엔 사람이기 때문에 의도치 않은 변경을 할 수도 있게 됩니다. 불변 값에 대해서는 final 키워드를 추가해서 Setter 사용을 막거나, Setter를 해당 필드에는 사용하지 않는 것으로 막을 수 있으나, Setter 사용을 지양하면 처음부터 이러한 걱정을 할 필요가 없습니다.

  • Setter 지양 시 대체 방법

    • 생성자

      public class Person {
      	private String name;
      	private String address;
      	private String phoneNumber;
      
      	public Person(String name) {
      		this.name = name;
      	}
      
      	public Person(String name, String address) {
      		this.name = name;
      		this.address = address;
      	}
      
      	public Person(String name, String address, String phoneNumber) {
      		this.name = name;
      		this.address = address;
      		this.phoneNumbber = phoneNumber;
      	}
      }
      
      • 다양한 클래스를 생성하기 위해 생성자 오버라이딩이 많이 필요함
    • 사용자 메소드

      📎예시

    • Builder 패턴

      public class Person {
      	private String name;
      	private String address;
      	private String phoneNumber;
      
      	@Builder
      	public Person(String name, String address, String phoneNumber) {
      		this.name = name;
      		this.address = address;
      		this.phoneNumbber = phoneNumber;
      	}
      }
      
      public class PersonService {
      	public PersonResponseDto createPerson(PersonRequestDto personRequestDto) {
      		Person person = Person.builder()
      				.name(personRequestDto.getName())
      				.address(personRequestDto.getAddress())
      				.build();
      		...
      	}
      }
      

    References

    https://bloowhale.tistory.com/97 https://dodop-blog.tistory.com/265 https://velog.io/@aidenshin/내가-생각하는-JPA-엔티티-작성-원칙 https://limdingdong.tistory.com/15