불변성과 가변성

0

TIL

목록 보기
151/183

프로젝트를 진행하던 도중 다른 팀원분의 PR에 또 다른분이 남기신 comment 내용이 눈에 띄었다.

    public void updateProduct(String name, String description, Integer price, Boolean isShown) {
        this.name = name;
        this.description = description;
        this.price = price;
        this.shown = isShown;
    }

객체의 정보를 업데이트하는 이 코드에 대해서
객체의 불변성을 지키기 위해 객체의 속성값을 직접 변경하는 대신 변경된 속성값을 가진 새로운 객체를 반환하는 것이 어떻겠냐라는 의견이었다.

원래 지금까지 프로젝트를 만들면서 수정하는 기능에 대해서는 Entity 클래스에 update 메서드를 만들어서 객체를 변경하는 방법을 사용해왔었는데
수정 기능에 여러번 들어봤던 불변성을 위한 새로운 객체 생성 방법은 익숙하지가 않아 이에 대해 알아보았다.


먼저 불변성과 가변성에 대해서 어떤 방식으로 접근하는 것이 더 올바른지에 대해서는
불변성은 함수형 프로그래밍이나 특정 동시 시스템과 같이 불변성이 관례나 요구 사항인 환경에서 선호되는 경우가 많고,
가변성은 성능이 더 좋고(불필요하게 새 객체를 생성하는 것을 방지) 더 직관적일 수 있기 때문에
상황에 따라서 다른 방식으로 접근하면 된다고 한다.

상황이 크게 와닿지 못해 comment를 남긴 팀원분에게 물어보니
객체의 상태값이 바뀔 수 있으면 그걸 가져다 쓰는 쪽에서 해당 객체에 원하는 값이 있을 것이라고 믿기 힘들어서 상태값이 안바뀌도록 불변성을 유지하려고 했었어요 라는 답변을 얻을 수 있었다.

예를들어서 내가 productName이 "A"라는 객체의 정보를 읽고싶은데
다른 누군가가 동시에 정말 말도안되는 타이밍으로 이 객체의 productName을 "B"라고 변경을 해버린다면 나는 productName이 "B"라는 정보를 얻게되고 내 머리속엔 물음표가 가득해질것이다.

추가로, 이러한 상황을 막기 위해서 컨벤션으로 @Setter의 사용 금지를 했던거도 불변성을 지키기 위함이었다.


해당 코드는

public Product updateProduct(String name, String description, Integer price, Boolean isShown) {
    return new Product(
        name != null ? name : this.name,
        description != null ? description : this.description,
        price != null ? price : this.price,
        isShown != null ? isShown : this.shown
    );
}

이런 식으로 새로운 객체를 생성하면서, PatchMapping이기 때문에 null로 들어올 수 있는 데이터는 기존의 값으로 저장하는 방법을 사용할 수 있다.

0개의 댓글

관련 채용 정보