본문은 Effective Java를 읽고 정리한 내용을 기반으로 작성된 글입니다.
이따금 인스턴스 필드들을 모아놓는 일 외에는 아무 목적도 없는 퇴보한 클래스를 작성하려 할 때가 있다. 이처럼 퇴보한 클래스는 public이어서는 안 된다!
[패키지 바깥에서 접근할 수 있는 클래스라면 접근자를 제공해야 한다]
: public 클래스에서는 필드를 모두 private으로 바꾸고 public 접근자(getter)를 추가해야 한다.
☑️ 접근자와 변경자 메서드를 활용해 데이터 캡슐화하기
class Point{
public double x;
public double y;
}
이런 클래스는 데이터 필드에 직접 접근할 수 있으니 캡슐화의 이점을 제공하지 못한다.
- API를 수정하지 않고는 내부 표현을 바꿀 수 없고, 불변식을 보장할 수 없다. (변경 범위가 넓다)
- ex) 필드 x의 이름을 x1으로 변경하고 싶다면, point.x로 필드에 접근하고 있는 모든 API를 point.x1으로 수정해야 한다.
- 필드에 접근할 때 부수 작업을 할 수 없다.
- ex) 필드에 제약이 필요한 경우, 개발자는 코드에서 필드를 사용할 때마다 제약 조건을 확인해야 한다.
다음과 같이 접근자를 제공함으로써 클래스 내부 표현 방식을 언제든 바꿀 수 있는 유연성을 얻을 수 있다.
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) {
assert x > 5;
this.x = x;
}
public void setY(double y) { this.y = y; }
}
- 필드의 제약조건 또한 메서드 내에서 구현하여 불변성을 고민하지 않아도 된다.
[package-private 클래스 혹은 private 중첩 클래스라면 데이터 필드를 노출해도 문제가 없다]
: 이 방식은 클래스 선언 면에서나 코드 면에서나 접근자 방식보다 훨씬 깔끔하다.
☑️ 클래스가 표현하려는 추상 개념만 올바르게 표현해주면 된다.
- 이 방식은 클래스 선언 면에서나 코드 면에서나 접근자 방식보다 훨씬 깔끔하다.
- pakage-private, private 클래스는 패키지 내부에서만 사용하거나 해당 클래스에서만 동작되기 때문에 패키지 바깥 코드는 전혀 손대지 않고도 데이터 표현 방식을 바꿀 수 있다.
그럼에도 불구하고 public 필드보다는 private 필드와 접근 메서드를 사용하는 것이 좋긴 하다.
☑️ public 클래스의 필드가 불변이라면
직접 노출할 때의 단점은 줄어들지만, 여전히 좋은 생각이 아니다.
[핵심 정리]
- public 클래스는 절대 가변 필드를 직접 노출해서는 안 된다.
- 불변 필드라면 노출해도 덜 위험하지만 완전히 안심할 순 없다.
- 하지만 package-private 클래스나 private 중첩 클래스에서는 종종 필드를 노출하는 편이 나을 때도 있다.
'Book > 이펙티브 자바' 카테고리의 다른 글
[Effective Java] item 18. 상속보다는 컴포지션을 사용하라 * (1) | 2023.10.06 |
---|---|
[Effective Java] item 17. 변경 가능성을 최소화하라 (0) | 2023.10.04 |
[Effective Java] item 15. 클래스와 멤버의 접근 권한을 최소화하라 (0) | 2023.09.24 |