JAVA/Java

Setter의 사용 금지

dodop 2021. 12. 13. 16:57

 

 

프로젝트 진행중 엔티티나 DTO에 setter를 사용하게 되는 일이 종종 발생하게 되는데,

이는 일관성 유지에 어려움 등의 여러가지 문제점으로 인해 사용이 금지된다. 

 

 

 

 

 

① Setter 사용의 의도를 알기 어려움
public ActivityCreateDTO saveActivity(ActivityCreateDTO activityCreateDTO) {

        Activity activity = new Activity();
        activity.setName(activityCreateDTO.getName());
        activity.setDescription(activityCreateDTO.getDescription());
        activity.setScore(activityCreateDTO.getScore());
        activityRepository.save(activity);

        activityRepository.save(activity);
        return new ActivityCreateDTO(activity);
}

보통 setter는 위와 같이 엔티티의 값을 변경하고자 할 때 많이 사용되는데 setter로 값을 변경하는 의도가 분명하지가 않다. 어떤 변화를 주기 위해서 값을 변경하는지 명확한 의도를 나타내지 않는다. 

 

 

public class Activity {

    private Integer id;
    private String name;
    private Integer score;
    private String description;

    public Activity(String name, Integer score, String description) {
        this.name = name;
        this.score = score;
        this.description = description;
    }

    // 비지니스 로직
    public Activity updateActivity( Activity requestActivity) {
        this.name = requestActivity.name;
        this.description = requestActivity.description;
        this.score = requestActivity.score;

        return this;
    }
}
    public ActivityCreateDTO updateActivity(ActivityCreateDTO activityCreateDTO,
        MultipartFile multipartFile) {
        Activity existingActivity = activityRepository.findById(activityCreateDTO.getId())
            .get();
        Activity requestActivity = activityCreateDTO.toActivity();
        Activity updatedActivity = existingActivity.updateActivity(requestActivity);
        activityRepository.save(existingActivity);
        return new ActivityCreateDTO(existingActivity);
    }

위와 같이 엔티티에 값을 변경하고자 하는 비지니스로직을 생성 해주고 service계층에서는 updateActivity 로직을 사용하므로서 값을 변경하고자 하는 의도를 지닌 로직명을 명확히 하고 변경 이유를 알려주도록 한다. 

 

 

 

 ② 값의 일관성 유지에 어려움

자바의 빈 규제에 따라서 setter 는 public 으로 모든 곳에서 접근이 가능하기 때문에 의도치 않게 값이 변경되는 경우가 발생할 수 있다. 

 

 

 

 @Builder의 사용

멤버 변수가 많고, 다양한 생성자를 가져야 하는 경우에는 객체 생성시점에 값을 넣어주어 객체 값의 일관성을 유지하도록 돕는 @Builder를 사용할 수 있다. 

 

public class ActivityCreateDTO {

    private Integer id;

    private String name;

    private Integer score;

    private String description;

    private String imageUrl;

    public ActivityCreateDTO(String name, Integer score, String description) {
        this.name = name;
        this.score = score;
        this.description = description;
    }
    
    public ActivityCreateDTO(Integer id, String name, Integer score, String description) {
        this.id = id;
        this.name = name;
        this.score = score;
        this.description = description;
    }
}

원래의 경우 setter값을 지양하고자 많은 생성자를 지니게 된다. 

 

public class ActivityCreateDTO {

    private Integer id;

    private String name;

    private Integer score;

    private String description;

    private String imageUrl;
    
    @Builder
    public ActivityCreateDTO(Integer id, String name, Integer score, String description) {
        this.id = id;
        this.name = name;
        this.score = score;
        this.description = description;
    }
}
Activity activity = Activity.Builder()
	.name("name")
        .score(12)
        .description("description")
        .build()

위와 같이 @Builder를 사용하게 되면 많은 생성자를 사용할 필요 없이 setter의 사용을 줄일 수 있다. 

 

public class Activity {
    
    protected Activity() {};
}

기본 생성자를 기본적으로 필요로하는 JPA의 경우 protected까지 생성자를 제어하는 것을 지원하므로 new Activity() 의 사용을 막을 수 있어 객체를 더욱 일관성 있게 유지할 수 있다. 

 

@NoArgsContructor(access = AccessLevel.PROTECTED)
public class Activity {
    
    protected Activity() {};
}

롬복을 사용하면 더 편하게 나타낼 수 있다. 

 

 

 

 

 

 

 

 

(참고한 사이트)

https://bloowhale.tistory.com/97

 

[Java] Setter 사용을 지양하자!!

들어가며 안녕하십니까 백엔드 개발자 지망생 BLoo 입니다. 이번 시간에는 제가 Entity와 DTO등에 Setter를 지양하고 있는데 그 이유를 한 번 정리하고자 포스팅하게 되었습니다. 보통 자바 클래스는

bloowhale.tistory.com

https://velog.io/@aidenshin/%EB%82%B4%EA%B0%80-%EC%83%9D%EA%B0%81%ED%95%98%EB%8A%94-JPA-%EC%97%94%ED%8B%B0%ED%8B%B0-%EC%9E%91%EC%84%B1-%EC%9B%90%EC%B9%99

 

JPA 엔티티 작성 - Setter 금지

엔티티를 작성함에 제가 생각하는 몇가지 원칙(?)이 있습니다.그중 엔티티(객체)의 Setter 사용 금지 원칙(?) 에 대해 알아보겠습니다.엔티티를 작성할 때 습관적으로 모든 필드에 Setter를 생성하는

velog.io