본문 바로가기
개발/Java

public VS private + getter

by kadokok 2023. 4. 2.

미션을 하다가, A 도메인이 가지고 있는 상수의 값을 B 도메인에서 필요로 하는 경우가 있었습니다.

지금까지 상수는 당연히 private static final 로 작성해왔는데, 위의 경우때문에 꽤 큰 고민에 빠졌습니다.

 

결론적으로 제가 생각한 선택지는 크게 3가지가 있었습니다.

 

  1. B 도메인에도 A 도메인이 가지고 있던 상수를 정의해서 사용한다.
    이 경우는 좋은 판단이 아니라고 생각했습니다. 해당 상수가 가지는 의미가 B 도메인이 가지는 책임과는 거리감이 있다고 느꼈기 때문입니다.

  2. 상수를 도메인 필드로 바꿔서 getter를 연다.
    이 경우도 썩 내키진 않았습니다. 이런 형태로 하면 블랙잭 게임 요구사항과는 다른 값(딜러의 이름이 더 이상 “딜러”로 한정되지 않는 것처럼!)들이 들어올 수 있고, 이는 요구사항을 벗어나는 오버엔지니어링일 수도 있겠다는 생각을 했습니다.

  3. 상수에 대한 getter를 연다.
    사실 제일 무난한 방법이었습니다. 다만 고민이 되었던 점은, 지금까지 getter를 인스턴스 필드 값에 대해서만 열어줬었는데, 상수에 대한 getter라고하니 어색한 부분이 없지 않아 있었습니다.

확실하게 해결이 안돼서, 이 내용을 코드 리뷰 질문으로 남겨두었는데 이런 답변이 왔습니다.

 

private 상수를 외부에서도 사용해야 한다면, 해당 상수의 접근 제어자를 변경하는 건 어떨까요?

 

음.. 이럴 생각은 못해봤는데, 다시 한 번 고민이 시작되었습니다.

그래서 일단은 좀 더 근본적인 문제를 생각해보기로 했습니다.

public VS private + getter

코드를 작성할 때, 객체의 필드 값 접근제어자는 대부분 private으로 두는 경향이 있습니다. 그리고 해당 필드 값이 다른 곳에서 필요하다면, getter 메서드를 열어서 접근할 수 있도록 만들어주죠.

 

그렇다면 이런 생각이 들 수 있습니다.

getter를 열어서 필드 값에 접근할 수 있게 할거면, 귀찮게 getter 코드 쓰지 말고 public으로 만들면 안되나?

 

왜 사람들은 필드 값을 굳이 private으로 감춰서 getter로 접근할 수 있게 하는 걸까요?

한 번 각각의 장단점을 비교해보면 좋을 것 같습니다.

public

장점

  • 간단하고 직관적입니다. 예를 들어, A 클래스의 foo 라는 변수에 접근하기 위해서는 A.foo 만 적어주면 되겠죠.
  • 다른 클래스에서도 쉽게 접근할 수 있습니다.

단점

  • 다른 클래스에서도 쉽게 접근할 수 있습니다.
  • 안정성이 떨어집니다. 외부에서 필드에 직접 접근해서 값을 변경할 수 있기 때문이죠.

private + getter

장점

  • 안정성이 올라갑니다. private 필드는 외부에서 직접 접근할 수 없고, 개발자가 만든 getter 메서드로만 접근할 수 있기 때문에, 개발자의 의도대로 사용되도록 유도할 수 있습니다.
  • getter는 메서드이기 때문에, 내부에 추가적인 로직을 넣어줄 수 있습니다. ex) 방어적 복사, validate 로직

단점

  • getter 메서드를 추가로 만들어줘야 하기 때문에, 코드가 조금 더 길어집니다.
  • 필드 접근을 위해서는 getter 메서드를 반드시 사용해야 합니다.

간단 요약

간단하게 요약하자면 이렇습니다.

 

public의 경우의 가장 큰 장점은 사용하기 편하다! 정도 입니다. 다만 안정성이 크게 떨어질 수 있습니다.

private + getter의 경우의 가장 큰 장점은 안정성입니다. 다만 사용성이 떨어질 수 있죠.

그렇다면 무엇을 써야하나?

먼저 필드의 경우를 먼저 봐볼까요?

오늘 날의 서비스 로직은 매우 복잡합니다. 또한 서비스 하나에 많은 돈들이 움직이고 있죠. 때문에, 로직이 개발자의 의도대로 흘러가지 않는다면, 매우 큰 경제적 손실을 불러일으킬 수 있습니다.

때문에 사용성을 조금 내려놓더라도 프로그램의 안정성을 챙길 수 있다면, 대부분의 개발자들은 당연히 안정성을 택할 것 같습니다.

즉, public 필드보다는 private 필드를 만들고, 이에 대한 getter를 여는 것이죠. 의도치 않은 값의 변경을 막기 위해서, getter 메서드에 방어적 복사와 같은 추가적인 로직을 첨가해 안정성을 올릴 수 있습니다.

 

그렇다면 이제 필드가 아닌 상수의 경우를 생각해보죠.

public 과 private + getter 를 나누었던 주된 이유가 무엇인가요? 바로 프로그램의 “안정성” 때문입니다. 여기서 말하는 “안정성” 이란 단어는 사실 “의도치 않은 값의 변경 여지가 존재하는가” 와도 같죠.

여기서 중요한 점은, 상수는 필드와는 달리 값이 변하지 않습니다. 이미 존재 자체가 안정적이라고 볼 수 있는 친구들이죠.

때문에, 만약 어떤 도메인 내부에 있는 상수 값이 다른 도메인에서 필요하다면, 굳이 코드를 늘려가며 private + getter 를 사용하여 안정성을 고려할 필요가 없다는 거죠. 단순히 상수의 접근제어자를 public 으로 바꿔주기만 하면 되는 일입니다.

결론

private + getter 는 필요에 따라 내부에 적절한 로직을 둬서 직접적인 값의 변경을 막을 수 있습니다. 때문에 필드에 경우에는 getter 메서드를 추가적으로 작성할 충분한 가치가 있죠.

 

다만 상수의 경우에는 애초에 불변입니다. 값이 변하지 않죠. 때문에 상수의 값이 다른 곳에서 필요하다면, getter 처럼 추가적인 메서드를 만들기보다는 접근제어자를 public 으로 수정하는 편이 더 간단하다고 볼 수 있죠.

댓글