조종 다음은 개발
article thumbnail

1 주차 미션을 마무리하고 코드 리뷰를 진행하던 중, 다른 분의 코드에서 어떤 분이 “getter 를 지양하는 코드를 작성하면 어떨까요??”라는 피드백을 달으신 것을 보았다.

그 동안 setter 를 지양해야 한다는 것은 알고 있었다. 그런데 getter 까지 지양해야 한다는 것은 어디선가 들어본 것 같기는 한데 자세한 이유를 모르고 있었다. 그래서 이번 기회에 한 번 알아보고자 한다.

🙄 왜 getter 를 지양해야 할까?

바로 본론으로 들어가서 왜 getter 를 지양해야 하는지 그 이유에 대해서 알아보자.

👻 캡슐화의 의미가 없어진다.

public Cars {
    private List<String> carNames;
    ...
}

보통 객체들은 위와 같이 필드값들을 private 으로 선언하여 캡슐화를 한다. 이를 통해 외부에서 내부 데이터를 무분별히 수정하지 못하도록 보호한다.
그런데 만약 getter 를 사용한다면 데이터가 안전히 보호될까??

Cars cars = new Cars("pobi", "juni", "jun");
List<String> carNames = cars.getCarNames();

carNames.removeAll(); // cars 에 있는 carNames 의 모든 값들 삭제!!

위와 코드를 통해 알 수 있듯이 getter 를 사용한다고 해서 값이 보호되지 않는다.
이러면 필드값들을 public 으로 사용한 것과 별 차이가 없다.

🤝 getter 에 대한 의존성이 올라간다.

보통 getter 를 사용하면 조회만 하는 것에서 끝나지 않는다.

public Cost {
    int amount;

    public int getAmount() {
        return amount;
    }
}
public String calculateGrade(Cost cost) {
    if (cost.getAmount() > 1000) {
        return "Gold";
    }
    if (cost.getAmount() > 500) {
        return "Silver";
    }
    if (cost.getAmount() > 250) {
        return "Bronze";
    }

}

위와 같이 사용자가 얼마나 사용했는지에 따라서 등급을 계산하는 코드가 있다고 해보자.
지금까지는 문제가 없다. 그런데 만약 요구사항이 변경되어서 Cost 가 사용량과 단가를 가지도록 변경되면 어떻게 될까?

public Cost {
    int unitPrice;
    int usage;
    ...
}

이렇게 요구사항이 변경되면 지금까지 getAmount() 를 사용했던 코드들을 전부 찾아서 수정해줘야 한다.
작은 프로젝트라면 큰 문제가 없지만 만약 수백 개의 파일이 있는 프로젝트라면 어떨까? 일일이 찾아서 수정하는 것만으로도 어마어마한 수고가 든다.
그렇기 때문에 getter 의 사용을 지양하는 것이다.

😡 그러면 getter 없이 어떻게 하라고?

그렇다면 어떻게 getter 를 사용하지 않을 수 있을까??
이 문제를 해결하기 위해서는 을 전달하는 것이 아닌 행동메시지 를 전달하는 방식으로 수정하면 된다.

위 예시를 수정해 보자.

public Cost {
    int amount;

    public String calculateGrade() {
        if (cost > 1000) {
            return "Gold";
        }
        if (cost > 500) {
            return "Silver";
        }
        if (cost > 250) {
            return "Bronze";
        }
    }
}

위와 같이 메시지를 객체가 전달하는 방식으로 수정하면 된다.
외부에서 값을 가져다가 계산하는 방식이 아닌, 객체 안에서 계산을 하여 메시지를 전달하는 것이다.

public Cost {
    int unitPrice;
    int usage;

    public String calculateGrade() {
        int cost = unitPrice * usage;
        if (cost.getAmount() > 1000) {
            return "Gold";
        }
        if (cost.getAmount() > 500) {
            return "Silver";
        }
        if (cost.getAmount() > 250) {
            return "Bronze";
        }
    }
}

만약 필드값이 변경된다 하여도 getAmount() 를 사용한 모든 곳을 찾아서 수정할 필요 없다.
단순히 Cost 객체 내부에서 정의된 메서드만 수정해 주면 된다.

⭐️ getXX 함수를 사용하지 말라는 것이 아니다.

가끔 핵심을 놓치고 단순히 getXXX 함수를 사용하면 안 된다는 사람들이 있다. getter 함수를 사용하지 말라는 것이 아니다.
단순히 값만 조회하는 경우에는 getter 함수를 사용해도 된다.
실제로 값을 출력하거나 DTO를 사용할 때는 getter를 사용할 수밖에 없다.
원본 필드를 수정하지 않고 의존성 있는 코드를 작성하지 않는 선에서 getter 를 사용하자!

profile

조종 다음은 개발

@타칸

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!