Back-End/객체프로그래밍

Getter사용을 지양해야 하는 이유, 예제

개도필 2023. 10. 27. 16:55

Getter사용을 지양하자!

왜??

 

1. 객체 캡슐화를 위반하는 행위

캡슐화가 잘 된 객체

  • 멤버 필드에게 접근하는 것을 허용하지 않음
  • 자신의 멤버 필드를 노출하지 않음
  • 클래스 안에 멤버 필드가 있는지조차 알 수 없음 

 

2. Getter를 통해 조건을 검사하면 변경에 취약하다.

다음 예제 코드는 고객의 도시가스 이용 요금에 따라 고객 등급을 출력하는 예제이다.

@Getter
class Customer {
    private long charge;
}
 
@Service
public class CustomerService {
    ...
    
    public void printMembershipGrade(Customer customer) {
        if (customer.getCharge() >= 100000) {
            System.out.println("Gold");
        } else if (customer.getCharge() >= 50000) {
            System.out.println("Silver");
        } else {
            System.out.println("Bronze");
        }
    }
    
    ...
}

 

코드 자체는 별 문제가 없어보이지만, 요구사항이 변경되어 고객이 요금 대신 사용량과 단가만 갖게 된다면?

@Getter
class Customer {
    private long usages;
    private long unitPrice;
}
  • CustomerService에서는 이러한 사실을 알지 못한다. 더 이상 존재하지 않는 이용 요금을 조회하려고 할테니 당연히 컴파일 에러가 발생하게 된다.
    • 모든 코드를 수정해야함,
  • 오류가 발생한 이유
    • 객체가 고객 등급을 결정하는 책임을 지지 않아서 발생한 문제이다.

 

그럼 Getter없으면 어떻게 하냐??

  • 정보를 주지말고, 정보에 관련 된 당사자(객체) 가 처리를 하자!

 

해답 예시1

위의 예시에서, Customer객체가, 고객 객체에게 고객 등급을 반환하면 된다!

class Customer {
    private long usages;
    private long amount;
    
    public String calcMembershipGrade() {
        long charge = usages * amount;
        
        if (charge >= 100000) {
            return "Gold";
        } else if (charge >= 50000) {
            return "Silver";
        } else {
            return "Bronze";
        }
    }
}
 
@Service
public class CustomerService {
    ...
    
    public void printMembershipGrade(Customer customer) {
        System.out.println(customer.calcMembershipGrade());
    }
    
    ...
}
  • 더 이상 CustomerService에서 고객의 등급을 출력하기 위해 고객의 상태를 알 필요가 없다.
  • 그저 고객 객체에게 고객 등급을 계산해 달라고 시키기만 하면 되는 것!

 

 

해답 예시2

  • 만약 자동차 주행 거리가 100km 가 넘었는지 알고 싶은 경우
class car {
   private int 거리;

   public car(int 거리){
       this.거리 = 거리;
   }

   public int get거리(){ return this.거리;}
}

  public static void main(String[] args) {
   if(car.get거리 >= 100km){
      System.out.println("100km 넘게 주행하셨네요 ~);
   else
      System.out.println("100km 안넘었어요! ");
}

여기서 get 을 사용하면 거리가 노출되니 바꿔보면, 

 

class car {
   private int 거리;

   public car(int 거리){
       this.거리 = 거리;
   }

   public int isOverKm(int km){ // 여기를 보자
         return 거리>= km;
}

  public static void main(String[] args) {
   if(isOverKm(100)){
      System.out.println("100km 넘게 주행하셨네요 ~);
   else
      System.out.println("100km 안넘었어요! ");
}
  • 정확한 거리를 알려주지 않더라도 내가 원하는 정보를 알게 된다.

 

 

 

  • 참고블로그

https://velog.io/@devel_sujin/Getter-Setter-를-쓰지-말아야하는-이유가-뭘까

https://lovethefeel.tistory.com/173

https://colabear754.tistory.com/173