티스토리 뷰

잘 설계된 모듈은 구현 세부사항을 전부 API 뒤쪽에 감춘다. 내부적으로 무슨 짓을 하는지는 신경 쓰지 않는다. 이 개념은 정보은닉(information hiding) 또는 캡슐화(encapsulation)라는 용어로 알려져 있으며, 소프트웨어 설계의 기본 원칙 가운데 하나다. 정보은닉이 좋은 성능을 보장하는 건 아니지만 성능 문제를 일으키는지 프로파일링 하는데 용의 하다. 또한 병행 개발이 가능하며, 다른 코드에 영향 없이 디버깅이나 성능 튜닝을 할 수 있다.

 

각 클래스와 멤버는 가능한 한 접근 불가능하도록 만들어라. 다시 말해서 정상적인 동작을 보증하는 한도 내에서 가장 낮은 접근 권한을 설정하라는 것이다.

 

 

클래스 접근 권한자


package-private(default)

  • public을 붙이지 않으면 해당 패키지 안에서만 유효한 개체가 된다.
  • 최상위 레벨 클래스나 인터페이스는 가능한 package-private로 선언해야 한다. 다음번 릴리즈 때 코드를 자유로이 변경, 삭제가 용이하다.

public

  • 전역적 객체가 된다.
  • 호환성을 보장하기 위해 해당 개체를 계속 지원해야 한다.

private nested class

클래스를 사용하는 클래스가 하나뿐이라면 private nested class(중첩 클래스)를 고려해야 한다.

하나의 클래스만이 해당 클래스의 접근 권한을 가지게 된다.

 

 

필드, 메서드, 중첩 클래스(nested class) 중첩 인터페이스(nested interface) 접근 권한자


private : 선언된 최상위 레벨 클래스 내부에서만 접근 가능하다.

package-private : 같은 패키지 내의 아무 클래스에서 접근 가능하다.

protected : 선언된 클래스 및 그 하위 클래스에서 접근 가능하다.

public : 어디에서도 접근 가능하다.

 

Serializeable을 구현하는 클래스의 멤버라면 private, default 라도 API로 새어나갈 수 있다. 직렬화 정보는 프록시 패턴을 이용하고, 암호화해서 전달해야 한다.

 

상위 클래스 메서드를 재정의 할때 원래 메서드의 접근 권한보다 낮은 권한을 설정할 수 없다.

 

객체 필드는 절대로 public으로 선언하면 안 된다. 변경 가능 public 필드를 가진 클래스는 다중 스레드에 안전하지 않다. 변경 불가능 객체를 참조하는 final 필드라 해도 public으로 선언하면 클래스의 내부 데이터 표현 형태를 유연하게 바꿀 수 없다.

 

public static final 상수는 변경 불가능 객체를 참조해야 한다. 참조 자체는 변경할 수 없지만 참조 대상 객체는 변경할 수 있으므로 문제가 된다. public static final 배열 필드를 두거나, 배열 필드를 반환하는 접근자(accessor)를 정의하면 안 된다.

 

final로 선언해도 배열과 같은 경우는 참조 대상 객체를 바꾸는 건은 얼마든지 가능하기 때문에 이런 문제에 대한 해경 방법은 두 가지가 있다. 하나는 public으로 선언된 배열은 private로 바꾸고, 변경이 불가능한 public 리스트(list)를 하나 만드는 것이다.

 

두 번째 방법은 배열은 private로 선언하고, 해당 배열을 복사해서 반환하는 public 메서드를 추가하는 것이다.

 

// 보안 문제를 초래할 수 있는 코드
pulbic static final Thing[] VALUES = {.....};

// 해결책 1
private static final Thing[] PRIVATE_VALUES = {.....};
public static final List<Thing> VALUES = Collections.unmodifiableList(Arrays.asList(PRIVATE_VALUES));

// 해결책 2
private static final Thing[] PRIVATE_VALUES = {.....};
public static final Thing[] values() {
	return PRIVATE_VALUES.clone();
}

요약해 보자면 접근권한은 가능한 최소한으로 해야 한다. public static final 필드를 제외한 어떤 필드로 public 필드로 선언하지 마라. 그리고 public static final 필드가 참조하는 객체는 변경 불가능 객체로 만들어라.

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함