아이템24. 멤버클래스는 되도록 static으로 만들라.

중첩클래스

  • 다른 클래스 안에서 정의된 클래스.
  • 자신을 감싼 바깥 클래스에서만 쓰여야한다. 그 외 쓰임새가 있다면 톱레벨 클래스로 선언할 것.
  • 정적 멤버 클래스, (비정적)멤버클래스, 익명 클래스, 지역 클래스 등이 있다.

정적 멤버 클래스

  • 다른 클래스 안에 선언되고, 바깥 클래스의 private 멤버에도 접근 가능을 제외하면 일반 클래스와 똑같음.
  • 개념상 중첩 클래스의 인스턴스가 바깥 인스턴스와 독립적으로 존재할 수 있다면 정적멤버클래스로 만들 것. (비정적 멤버 클래스는 바깥 인스턴스 없이는 생성할 수 없다)

결론.

  1. 메서드 밖에서도 사용해야 하거나 메서드 안에 정의하기엔 너무 길다면 멤버클래스로 만들 것.
    1. 멤버클래스의 인스턴스 각각이 바깥 인스턴스를 참조한다면 비정적으로 만들 것.
    2. 그렇지 않으면 정적으로 만들 것.
    3. 중첩클래스가 한 메서드 안에서만 쓰이면서, 그 인스턴스를 생성하는 지점이 단 한곳이고 해당 타입으로 쓰기에 적합한 클래스나 인터페이스가 이미있다면 익명 클래스로 만들것.
    4. 그렇지 않으면 지역클래스로 만들 것.

아이템 17. 변경가능성을 최소화하라.


 

불변클래스

  • 인스턴스의 내부 값을 수정할 수 없는 클래스
  • 불변 객체는 단순하다. 생성된 시점의 상태를 파괴될 때까지 그대로 간직한다.
  • 스레드세이프하여 따로 동기화할 필요가 없다. 불변객체는 안심하고 공유할 수 있다.
  • clone메서드나 복사 생성자는 제공하지 않는 게 좋다.
  • 자유롭게 공유가 가능하고, 불변 객체끼리는 내부 데이터를 공유할 수 있다.
  • 맵의 key와 set의 원소로 쓰기에 좋다.
  • 실패 원자성을 제공한다

불변클래스를 만드는 법

  1. 객체의 상태를 변경하는 메서드를 제공하지않는다.
  2. 클래스를 확장할 수 없도록 한다. ( 대표적으로 클래스를 final로 선언)
  3. 모든 필드를 final로 선언한다
  4. 모든 필드를 private으로 선언한다.
  5. 자신 외에는 내부의 가변 컴포넌트에 접근할 수 없도록 한다.

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

잘 설계된 컴포넌트?

  • 잘 설계된 컴포넌트는 바로 클래스 내부 데이터와 내부 구현정보를 외부 컴포넌트로부터 얼마나 잘 숨겼느냐로 판단.
  • 잘 설계된 컴포넌트는 모든 내부 구현을 완벽히 숨겨, 구현과 api를 깔끔히 분리.
  • 오직 api로만 다른 컴포넌트와 소통하며 서로의 내부 동작 방식에는 관심도 없다. (정보은닉, 캡슐화)

정보은닉의 장점.

  • 개발속도를 높인다. 여러 컴포넌트를 병렬로 개발할 수 있기 때문.
  • 관리비용을 낮춘다. 각 컴포넌트를 더 빨리 파악하여 디버깅이 가능. 다른 컴포넌트로 교체하는 부담도 낮다.
  • 성능최적화에 도움을 줄 수 있다. 다른 컴포넌트에 영향 주지않고 해당 컴포넌트만 최적화 할 수 있기 때문.
  • 소프트웨어 재사용성을 높인다. 독자적으로 동작할 수 있는 컴포넌트라면 낯선 환경에서도 유용하게 쓰일 가능성이 높기 때문.
  • 큰 시스템을 제작하는 난도를 낮춰준다. 전체가 완성안됐더라도 개별 컴포넌트의 동작을 검증할 수 있기 때문.

정보은닉을 위한 장치

  • 접근제한자.
    • 모든 클래스와 멤버의 접근성을 가능한 한 좁혀야한다.
    • 패키지외부에서 쓸 이유 없다면 package-priave으로 선언하자. 그럼 내부구현이 되어 언제든 수정할 수 있다.
      • public으로 선언한다면 api가 되므로 영웡히 관리 필요.
    • 한 클래스에서'만' 사용하는 package-private 톱레벨 클래스나 인터페이스는 이를 사용하는 클래스 내에 private static으로 중첩시키자.
    • 공개 API를 설계한 후 그 외의 모든 멤버들은 private으로 만들자. 그런 다음 같은 패키지의 다른 클래스가 접근해야 하는 멤버에 한하여 package-private으로 풀어주자.

toString을 항상 재정의하라.

  • 오버라이딩 안하면 단순히 클래스_이름@16진수로_표시한_해시코드
  • toString을 잘 구현한 클래스는 사용하기에 즐겁고, 디버깅이 쉽다.
  • 객체가 가진 주요 정보 모두를 반환하게끔 재정의하자.

정리

모든 구체클래스에서 Object의 toString을 재정의하자. 상위클래스에서 이미 알맞게 재정의한 경우 제외. toString은 해당 객체에 관한명확하고 유용한 정보를 읽기좋은 형태로 반환해야한다.

+ Recent posts