peaches-book-study / effective-java

이펙티브 자바 3/E
0 stars 2 forks source link

Item 15. 클래스와 멤버의 접근 권한을 최소화하라 #14

Open byunghyunkim0 opened 7 months ago

byunghyunkim0 commented 7 months ago

Chapter : 4. 클래스와 인터페이스

Item : 15. 클래스와 멤버의 접근 권한을 최소화하라

Assignee : byunghyunkim0


🍑 서론

잘 설계된 컴포넌트는 내부 구현을 숨기고, 구현과 API를 깔끔하게 분리한다. 오직 API를 통해서만 다른 컴포넌트와 소통하며 서로의 내부 동작 방식에 영향을 주지 않는다.

정보 은닉의 장점

class Child extends Parent { // 더 좁은 범위로 사용하였기 때문에 컴파일 오류 @Override protected void test() { super.test(); } }

- 단지 코드를 테스트하려는 목적으로 클래스, 인터페이스, 멤버의 접근 범위를 넓히려 할때는 적당한 수준까지는 넓혀도 괜찮다.
    - public 클래스의 private 멤버를 package-private까지 허용
    - 즉, 테스트만을 위해 클래스, 인터페이스, 멤버를 공개 API로 만들어서는 안된다.
## 주의점
### public 클래스의 인스턴스 필드는 되도록 public이 아니어야 한다.
- 필드가 가변 객체를 참조하거나, final이 아닌 인스턴스 필드를 public으로 선언하면 값을 제한할 힘을 잃게 된다. (필드와 관련된 모든 것에 불변식을 보장할 수 없게 된다.)
- 필드가 수정될 때 다른 작업을 할 수 없게 되므로 public 가변 필드를 갖는 클래스는 일반적으로 thread-safety하지 않다.
- 예외적으로 상수에 대해서 public static final 필드로 공개해도 좋다.
    - 관례상 이름을 대문자 알파벳으로 쓰고, 각 단어 사이에 밑줄(_)을 넣는다.
    - 반드시 기본 타입 값이나 불변 객체를 참조해야 한다.
### 클래스에서 public static final 배열 필드를 두거나 이 필드를 반환하는 접근자 메서드를 제공해서는 안된다.
- 클라이언트에서 그 배열의 내용을 수정할 수 있다.
```java
// 보안 허점이 숨어있음.
public static final Thing[] VALUES = {...};

해결책

  1. public 배열을 private으로 만들고 public 불변 리스트를 추가한다.
    private static final Thing[] PRIVATE_VALUES = { ... };
    public static final List<Thing> VALUES = Collections.unmodifiableList(Arrays.asList(PRIVATE_VALUES));
  2. 배열을 private으로 만들고 그 복사본을 반환하는 public 메서드를 추가한다(방어적 복사).
    private static final Thing[] PRIVATE_VALUES = { ... };
    public static final Thing[] values() {
    return PRIVATE_VALUES.clone();
    }

    모듈 (패키지들의 묶음)

    • 자바 9부터 모듈 시스템이 도입되었고, 두 가지 암묵적 접근 수준이 추가되었다.
    • 패키지 중 공개(export)할 것들을 관례상 module-info.java파일에 선언한다.
    • protected, public 멤버라도 해당 패키지를 공개하지 않았다면 모듈 외부에서 접근할수 없다.
    • 모듈의 JAR 파일을 자신의 모듈 경로가 아닌 애플리케이션 클래스패스에 두면 그 모듈 안의 모든 패키지는 모듈이 없는 것처럼 행동한다. 공개 여부와 상관없이 public클래스의 public, protected 멤버를 모듈 밖에서도 접근할 수 있게 된다. (대표적인 예가 JDK)

      🍑 결론

    • 프로그램 요소의 접근성은 가능한 최소한으로 해라.

Referenced by

hyunsoo10 commented 6 months ago

좋은 글 잘 읽었습니다