개발 기록
[이펙티브 자바] 아이템 15 본문
(15) 클래스와 멤버의 접근권한을 최소화해라
- 정보은닉 : 소프트웨어에서 사용하는 객체에 대한 구체적인 정보를 노출시키지 않도록 하는 기법
### 정보은닉의 장점
1. 시스템 개발 속도를 높인다. (병렬 개발 가능)
- 정보은닉을 위해 인터페이스를 설계하게 되면 , 인터페이스를 사용하는 쪽, 구현하는 쪽 동시에 개발 진행 가능.
내부 로직이 없어도 메서드 자체를 호출 가능하기 때문에 개발 가능.
2. 시스템 관리 비용을 낮춘다.
- 인터페이스를 통해 각 컴포넌트를 더 빨리 파악할 수 있다. 다른 컴포넌트로 교체하는 부담도 적다.
3. 성능 최적화에 도움을 준다.
- 정보은닉 자체가 성능에 도움이 되는 것은 아니고, 다른 컴포넌트에 영향을 주지 않고 특정 컴포넌트만 최적화 가능하다.
4. 소프트웨어 재사용성을 높인다.
- 독자적으로 동작할 수 있는 컴포넌트라면 다른 프로젝트에서도 그대로 사용할 수 있다.
5. 시스템 개발 난이도를 낮춘다.
- 시스템 전체가 완성되지 않은 상태에서도 개별 컴포넌트의 동작을 검증할 수 있다.
### 클래스, 인터페이스, 멤버의 접근 제한자 제대로 활용하기
- 기본 원칙 : 소프트웨어가 올바로 동작하는 한 항상 가장 낮은 접근 수준을 부여해야한다.
** 접근 제한자
클래스 내부 | 동일 패키지 | 하위 클래스 | 그 외의 영역 | |
public | O | O | O | O |
protected | O | O | O | X |
package-private (default) |
O | O | X | X |
private | O | X | X | X |
1. 톱레벨 클래스와 인터페이스
- 부여할 수 있는 접근 수준 : package-private , public
-> 패키지를 외부에서 쓸 이유가 없다면 default로 선언. 그러면 이들은 클라이언트에 피해 없이 수정 가능.
ex. 구현체 같은 경우는 내부 클래스에서만 알면 되기 때문에 default가 적절하다.
class DefaultMemberService implements MemberService {
}
- 이를 사용하는 클래스 안에 private static으로 중첩시켜 보기.
-> 바깥 클래스 하나에서만 접근 가능. 바깥 클래스의 멤버들에 대한 접근이 불가능.
만약 내부 클래스에서 외부 클래스의 필드를 참조하고 싶다면 private class로.
class DefaultMemberService implements MemberService {
private static class MemberRepository {
}
}
2. 멤버 (필드,메서드,중첩 클래스, 중첩 인터페이스)
- 부여할 수 있는 접근 수준 : 4가지
- 클래스의 공개 API를 세심히 설계한 후, 그 외의 모든 멤버는 private으로 만들자. 그런 다음, 같은 패키지의 다른 클래스가 접근해야 하는 멤버에 한하여 제한자 제거.
** 상위 클래스의 메서드를 재정의할 때는 그 접근 수준을 상위 클래스에서보다 좁게 설정 할 수 없다.
-> 리스코프 치환 원칙. (상위 클래스의 인스턴스는 하위 클래스의 인스턴스로 대체해 사용 가능해야함)
- public 클래스의 인스턴스 필드는 되도록 public이 아니어야한다. 예외 : 상수용 public static final 필드
- 테스트만을 위해 멤버를 공개 API로 만들어서는 안 된다.
- public static final 배열 필드를 두거나 이 필드를 반환하는 접근자 메서드를 제공하면 안된다.
-> 클라이언트에서 배열을 수정할 수 있게 된다.
// 보안 허점이 숨어 있다.
public 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();
}
'JAVA' 카테고리의 다른 글
[이펙티브 자바] 아이템 21,22 (0) | 2024.11.19 |
---|---|
[이펙티브 자바] 아이템 18 (0) | 2024.11.04 |
[이펙티브자바] 아이템12 (0) | 2024.10.23 |
[이펙티브 자바] 아이템 11 (1) | 2024.10.15 |
[이펙티브 자바] 아이템 7,8 (2) | 2024.10.03 |