1. 캡슐화 원칙 위반

    1. 객체지향의 기본 원칙 중 하나는 데이터 은닉입니다.
    2. 모든 필드에 public setter가 열려있으면, 외부에서 객체 내부 상태를 마음대로 변경할 수 있어 안정성이 떨어집니다.
  2. 예시

    @Entity
    public class User{
    	private String email;
    	
    	public void setEmail(String email){
    		this.email = email;
    	}
    }
    

    c. 외부에서 user.setEmail(”[email protected]”) 처럼 임의로 변경 가능

    d. 데이터 무결성(Valid Data)을 보장하기 어려움

  3. 불변성 손상

    1. 엔티티가 생성 후 특정 필드는 변경되지 않아야 하는 경우가 많습니다.
    2. public setter 가 열려있으면 의도치 않게 변경될 수 있음
    3. 불변 객체를 만들면 버그 에방과 동시성 문제 해결에 유리합니다.
  4. 도메인 로직 보호

    1. 엔티티는 단순히 데이터를 담는 DTO가 아니라 비즈니스 로직을 갖는 객체입니다.

    2. 모든 필드를 외부에서 바꿀 수 있게 하면 도메인 규칙이 깨질 위험이 있습니다.

    3. 예시

      @Entity
      public class BankAccount{
      	private BigDecimal balance;
      	
      	public void deposit(BigDecimal amount){
      		if(amount.compareTo(BigDecimal.ZERO) <=0) throw new IllegalArgmentException();
      		balance = balance.add(amount);
      	}
      
      }
      
  5. Builder

    1. 특징
      1. 복잡한 객체를 안전하게 생성하기 위한 디지안 패턴
      2. 생성자에 인자가 많을 때 순서 헷갈림, 선택적 필드 문제를 해결
      3. Setter 없이 객체를 생성하면서 가독성과 안전성을 동시에 확보
    import lombok.Builder;
    import lombok.Getter;
    
    @Getter
    @Builder
    public class User{
    	private final String email;
    	private final String name;
    	provate final int age;
    }
    

객체생성

User user =User.builder()
			.email("[email protected]")
			.name("민상")
			.age(28)
			.build();
  1. 가독성 좋은

    1. 필드 순서에 상관없이 지정 가능
  2. Setter 없이 초기화 가능

    1. 불변 객체 설계 가능
  3. 검증 로직 포함

    1. Builder만 사용하면 값 검증이 자동으로 되지 않음
    2. 생성자에 검증 로직 추가 가능
    @Builder
    public user (String email, String name, int age){
    	if(email ==null || email.isBlank()) throw new IllegalArgumentException("Email required");
    	if(name ==null || name.isBlank()) throw new IllegalArgumentException("Name required");
    	    if(age < 0) throw new IllegalArgumentException("Age must be non-negative");
     this.email =email;
     this.name = name;
     this.age = age;
    
    }
    
  4. Builder + 도메인 메서드 조합

    User user =User.builder()
    					.email("[email protected]")
    					.name("민상")
    					.age(28)
    					.build();
    					
    //상태 변경은 도메인 메서드로만
    user.changeEmail("[email protected]");
    
    1. Builder → 초기화 안전
    2. 도메인 메서드 → 상태 변경 안전
    3. Setter없이도 캡슐화 유지 가능