[Effective Java] 아이템16 - public 클래스에서는 public 필드가 아닌 접근자 메서드를 사용하라
아래와 같은 클래스는 public
이어서는 안된다.
class Point {
public double x;
public double y;
}
- 데이터 필드에 직접 접근할 수 있어서 캡슐화 X
- 클래스 자체를 수정하지 않는 한 클라이언트에서 이 클래스 내부 표현을 바꿀 수 없음
- 클라이언트 측에서 값을 변경할 수 있으므로 불변식 보장이 안됨
1. public
클래스는 필드를 모두 private
으로 바꾸고 접근자(getter)를 추가한다.
class Point {
private double x;
private double 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;}
}
실무에서 많이 본 코드일 것이다. (물론 캡슐화를 위한 코드였는지는 몰랐음 ㅋㅋ)
접근자를 제공한다면, 필드를 클라이언트가 사용하고 있어도 내구 구현방식을 자유롭게 변경할 수 있다.
실제로 java.awt.package.Point
클래스는 public 임에도 불구하고 필드를 public으로 노출하고 있다. 심각한 성능 문제는 오늘날까지도 해결되지 못했다. [아이템67]
public class Point extends Point2D implements java.io.Serializable {
/**
* The X coordinate of this {@code Point}.
* If no X coordinate is set it will default to 0.
*
* @serial
* @see #getLocation()
* @see #move(int, int)
* @since 1.0
*/
public int x;
/**
* The Y coordinate of this {@code Point}.
* If no Y coordinate is set it will default to 0.
*
* @serial
* @see #getLocation()
* @see #move(int, int)
* @since 1.0
*/
public int y;
... 중략
}
2. public
클래스의 필드가 불변이라면 공개해도 좋다.
불변이라면 불변식은 보장할 수 있다. 하지만 클라이언트 측에서 해당 값을 가공할 수는 없다.
public class Time {
private static final int HOURS_PER_DAY = 24;
private static final int MINUTES_PER_HOUR = 60;
public final int hour;
public final int minute;
public Time(int hour, int minute) {
this.hour = hour;
this.minute = minute;
}
}
댓글남기기