brunch

You can make anything
by writing

C.S.Lewis

by 이승현 Mar 13. 2018

클래스와 인터페이스

#13 클래스와 그 멤버의 접근성을 최소화하자

Effective Java - 클래스와 인터페이스


#13 클래스와 그 멤버의 접근성을 최소화하자


잘 설계된 모듈은 외부 API 부분과 내부 구현 부분으로 나눠서 다른 모듈과 최소한의 상호작용만으로 동작합니다.


이를 정보 은닉(information hiding)이라 불리고 있는데, 이를 위해 접근성을 최소화하는 방법에 대해 알아보겠습니다.




정보 은닉(information hiding)


정보 은닉이란, 시스템을 구성하는 모듈들 간의 결합도를 낮춰서 모듈 별로 개발, 테스트, 최적화, 사용 및 수정이 가능하도록 합니다.


정보 은닉은 시스템을 구성하는 데 있어서 여러 장점이 있습니다.

각 모듈을 병행 개발할 수 있어서 시스템 개발이 빨라진다.

모듈을 더 빨리 파악할 수 있다.

다른 모듈에 대해 영향을 주지 않고 수정이 가능해, 유지 보수 부담이 줄어든다.

모듈을 최적화할 수 있다.

재사용성을 증가시킨다.

모듈 별 성공 여부 입증을 통해 개발 시 위험 부담을 줄여준다.


결론은 정보 은닉을 통해 프로그램의 성능을 향상하기보다는 개발 퍼포먼스를 향상할 수 있습니다.




접근 변경자(access modifier)


자바에서 제공하는 접근 변경자는 4가지입니다.

private - 멤버가 선언된 최상위 클래스 내에서만 접근 가능

(default) - 멤버가 선언된 클래스가 속한 패키지의 모든 클래스에서 접근 가능

protected - (default) + 멤버가 선언된 클래스의 서브 클래스로부터 접근 가능

public - 어디에서든 이 멤버에 접근 가능


접근 변경자를 지정하는 원리는 간단합니다.

각 클래스나 멤버의 접근 허용을 가능한 최소화하는 겁니다.

각 기능이 올바르게 동작하는 범위 내에서 가장 낮은 접근 수준(private)부터 지정하면 됩니다.




접근 변경자 지정


1. 우선 다른 모듈과 상호작용하는 외부 public API를 우선 신중하게 결정하고 다른 멤버들은 private로 지정합니다.

2. 같은 패키지의 다른 클래스가 꼭 접근할 필요가 있을 때만 default로 지정합니다.

3. 서브 클래스에서 꼭 접근할 필요가 있을 때만 protected로 지정합니다.


이러한 방법을 통해 접근 변경자들을 신중하게 지정할 수 있습니다.

무턱대고 접근 수준이 높게 지정한다면, 모듈 간 결합도가 높아져 유지 보수가 힘들어지게 됩니다.


접근 변경자를 지정할 때 몇 가지 제한 사항들이 있습니다.

1. 상속 관계에서 서브 클래스의 오버라이드 메서드는 슈퍼 클래스에서 지정한 접근 수준보다 더 낮게 지정할 수 없습니다.

ex) super class : protected / sub class : protected, default, private

2. 인터페이스의 모든 멤버는 자동적으로 public입니다.

3. 인스턴스 필드는 절대로 public으로 해선 안됩니다.

public 이면 외부에서 이 필드의 값을 임의로 변경할 수 있으므로 원자성을 보존할 수 없습니다.

4. public static final 필드 상수는 기본형 데이터 값이나 불변 객체 참조만 가져야 합니다.

만약 가변 객체라면, 외부에서 이를 변경할 수 있기 때문입니다.


// 심각한 보안상의 허점
public static final Thing[] VALUES = {...};
// 첫 번째 해결 방법
private static final Thing[] PRIVATE_VALUES = {...};
public static final List<Thing> VALUES =     Collections.unmodifiableList(Arrays.asList(PRIVATE_VALUES));
// 두 번째 해결 방법
private static final Thing[] PRIVATE_VALUES = {...};
public static final Thing[] values() {
    return PRIVATE_VALUES.clone();
}




결론은, 가능한 접근성을 줄여야 합니다.

클래스를 설계할 때는 최소한의 public API를 결정

클래스의 멤버들이 불필요하게 API의 한 부분이 되지 않도록 해야 함

public static final 상수를 제외하고 public 클래스에서는 어떤 public 필드도 있어선 안됨.

public static final 상수는 반드시 불변 객체




매거진의 이전글 모든 객체에 공통적인 메서드
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari