Public 클래스 사용 시
class Point { public double x; public double y; }
- 위와 같은 클래스는 데이터 필드에 직접 접근할 수 있으니 캡슐화의 이점을 제공하지 못함
- API를 수정하지 않고는 내부 표현을 바꿀 수 없고, 불변식을 보장할 수 없으며 외부에서 필드에 접근할 때 부수 작업을 수행할 수도 없음
⇒ 필드들을 모두 private으로 바꾸고 public 접근자(getter)를 추가하기
class Point { private double x; private double y; public Point(double x, double y) { this.x = x; this.y = y; } public double getX() { return x; } public double getY() { return y; } public void setX(double x) { this.x = x; } public void setY(double y) { this.y = y; } }
- 접근자를 제공함으로써 클래스 내부 표현 방식을 언제든 바꿀수 있는 유연성을 얻을 수 있음
- 필드 공개 시, 이를 사용하는 클라이언트가 생기므로 내부 표현 방식 마음대로 못 바꿈
- 필드가 불변이면 직접 노출 시 단점이 조금은 줄어들지만 여전히 API를 변경하지 않고는 표현 방식 바꿀 수 없고, 필드 읽을 때 부수 작업 수행할 수 없다는 단점은 여전함
Package-private 클래스 or private 중첩 클래스
- package-private 클래스 혹은 private 중첩 클래스라면 데이터 필드를 노출한다 해도 하등의 문제가 없다
- 클라이언트 코드가 이 클래스 내부 표현에 묶이기는 하지만, 클라이언트 또한도 패키지 안에 있기 때문에 패키지 바깥 코드를 손대지 않고 표현방식 변경 가능함