코딩못하는사람

아이템 15,16] 클래스와 멤버의 접근 권한을 최소화 본문

자바 메모장/이펙티브 자바

아이템 15,16] 클래스와 멤버의 접근 권한을 최소화

공부절대안함 2021. 7. 3. 20:55

[아이템15]클래스와 멤버의 접근 권한을 최소화

어설프게 설계된 컴포넌트와 잘 설계된 컴포넌트의 차이는 클래스 내부 데이터와 내부 구현 정보를 외부 컴포넌트로 부터 얼마나 잘 숨겼는지에 의해 결정된다.

잘 설계된 컴포넌트는 모든 내부구현을 숨기고 구현과 API를 깔끔하게 분리해서 서로의 내부 동작방식을 알 필요가 없게된다. 이것을 정보은닉 및 캡슐화라고 부른다.

 

정보은닉의 장점

  • 시스템 개발 속도 상승 (여러가지 컴포넌트를 병렬적으로 개발 가능)
  • 시스템 관리 비용 절감 (디버깅 및 다른 컴포넌트로 교체하는 부담이 적다)
  • 성능최적화에 도움
  • 소프트웨어 재사용성을 높인다.(외부 의존도가 거의 없고 독자적이라면 낯선 환경에서도 사용가능)
  • 큰 시스템 제작 난이도를 낮춰준다. (전체가 완성되지 않아도 개별 컴포넌트의 동작을 검증할 수 있어서)

자바의 접근 제한자

  • private: 멤버를 선언한 톱레벨 클래스에서만 접근할 수 있다.
  • package-private(default): 멤버가 소속된 패키지 안의 모든 클래스에서 접근 할 수 있다.
  • protected: package-private의 접근 범위를 포함하며, 이 멤버를 선언한 클래스의 하위 클래스에서도 접근할 수 있다.
  • public: 모든 곳에서 접근 할 수 있다.

 

접근 제한자를 제대로 활용하여 모든 클래스와 멤버의 접근성을 가능한 한 좁혀야 한다.다시 말해 가장 낮은 접근수준을 부여해야 한다.

 

클래스 레벨 접근 제한자

톱레벨 클래스(파일명 = 클래스명)와 인터페이스에 부여할 수 있는 접근 수준은 package-private와 public이다.

1.public으로 사용하면 공개 API가 되고 하위 호환을 위해 영원히 관리해야 한다.

2.package-private로 사용하면 해당 패키지에서만 사용 가능하여 다음 릴리즈에 내부로직을 변경해도 괜찮다.

 

이너 클래스 사용

한 클래스에서만 사용하는 package-private톱레벨 클래스나 인터페이스를 private static으로 중첩시켜보자.

private static으로 중첩시키면 바깥 클래스 하나에서만 접근할 수 있다.

https://jaehun2841.github.io/

 

private과 package-private은 해당 클래스의 구현에 해당하므로 공개 API에 영향을 주지 않는다.

public클래스는 그 패키지의 API인 반면 private과 package-private은 내부구현이다.

public 일 필요가 없는 클래스의 접근수준을 package-private로 줄이는 것이 중요하다.

우선 모든 멤버를 private로 만들고 필요할 경우 점차 늘려주도록 하자.

 

메서드를 재정의 할 경우 리스코프 치환 원칙에 의해 상위 클래스보다 접근수준을 좁힐 수 없다. ( 단 인터페이스를 구현하는 경우는 모두pulbic으로 해야한다)

 

코드를 테스트 하려는 목적으로 접근 범위를 넓히는 것을 주의하라.

private-> package-private까지는 괜찮지만 그 이상은 API에 문제가 될 수 있다.

 

public 클래스의 인스턴스 필드는 되도록 public이 아니어야 한다.

인스턴스 필드가 public이라면 불변식을 보장할 수 없다. thread safe하지 않다.

(상수라면 관례대로 public static final로 공개해도 된다)

 

public static final 배열 필드를 가지지 말자.

배열은 가변클래스이므로 배열 자체에 대한 참조는 변경할 수 없지만 배열의 각 내용은 변경 가능하기 때문이다.

 

배열 필드를 갖고자 한다면 private로 만들고 public 불변 리스트를 추가하는 방법, private로 만들고 복사본을 반환하는 방법이 있다.(방어적 복사)

 

[아이템16] public 클래스에서는 public 필드가 아닌 접근자 메서드를 사용하라.

퇴보 클래스

class Point {
  public double x;
  public double y;
}

클래스의 데이터 필드에 직접 접근하여 수정이 가능한 퇴보한 클래스이다. 이러한 클래스는 캡슐화의 장점을 갖지 못한다. 불변식을 보장할 수 없고,API를 수정하지 않고는 내부 표현식을 바꿀 수 없다.

 

접근자와 변경자 메서드를 활용해 캡슐화한 클래스

class Point {
  private double x;
  private double y;

  public Point (double x, double y) {
    this.x = x;
    this.y = 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; }
}

public  클래스라면 접근자와 수정자를 만들어주자.

클래스 내부 표현방식을 언제든지 바꿀 수 있는 유연성을 제공하자.

package-private or private 중첩클래스라면 데이터 필드를 노출해도 상관없다(톱레벨 및 같은 패지키에서만 사용되기 때문)

public 클래스는 절대 가변 필드를 노출하지 말자

 

 

출처 https://jaehun2841.github.io/2019/01/19/effective-java-item15/#%EC%8B%9C%EC%8A%A4%ED%85%9C-%EA%B4%80%EB%A6%AC-%EB%B9%84%EC%9A%A9%EC%9D%84-%EB%82%AE%EC%B6%98%EB%8B%A4

Comments