effective java 4장 클래스와 인터페이스

bluesky·2023년 12월 2일

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

  • 말 그대로!
  • 최소화 했을떄 노출이 최소로 되니 최적화에도 도움을 주고, 재사용성도 높이고 난이도도 낮춤.

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

  • public 메서드는 캡슐화의 장점을 못누림.

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

  • 불변 클래스를 이용해보는 건 어떠한가?

    • 만드는 규칙
      • 확장 막는다.
      • final, private, 외부에서 가변 컴포넌트 접근 막는다.
    • 단점
      • 한편 불변 클래스의 단점도 있다. 값이 다르다면 반드시 독립된 객체로 만들어야 한다
  • ex) 하위 호환성이 발목을 잡아 지금까지 못 고친 케이스

아이템 18. 상속보다는 컴포지션을 사용하라

  • 상속은 캡슐화 깨트려
    • addAll 115
    • ex) 상속 관계에 놓인 두 클래스에서 메소드를 재정의 할경우 문제가 생긴다.
  • 117 컴포지션의 이점.
    • 컴포지션 과 전달의 조합 → 위임. Delegation
  • 120 Stack → Vector, Properties → Hashtable

아이템 19. 상속을 고려해 설계하고 문서화하라. 그러지 않았다면 상속을 금지하라

  • 재정의 가능 메서드를 호출해서는 안된다.
  • 문서 최대한 남겨놔야.. 실수 가능성 비일 비재..
    • 이거 3자 한테 시켜서 이거 활용해서 3개는 만들어 봐야 안다.
  • 상속용 클래스의 생성자는 직접적으로든 간접적으로든 재정의 가능 메서드를 호출해서는 안된다.
    • private, final, static 메서드는 재정의가 불가능함.

아이템 20. 추상 클래스보다는 인터페이스를 우선하라

  • 여러개를 구현할수 있음.
  • 추상 클래스의 상속과 달리 인터페이스 구현은 하나에 종속적일 필요도 없
  • **인터페이스는 계층구조가 없는 타 프레임워크를 만들 수 있다.**
public interface Singer { // 가수
    AudioClip sing(Song s);
}

public interface Songwriter { // 작곡가
    Song compose(int chartPosition);
}

// 그렇다면, 노래도 부르고 작곡도 하는 싱어송라이터는?
public interface SingerSongWriter extends Singer, Songwriter {
    AudioClip strum();
    void actSensitive();
}

아이템 21. 인터페이스는 구현하는 쪽을 생각해 설계하라

  • 디폴트 메서드를 조심히 사용하자.
    • 하위에 이미 구현 되어 있을 수도 있다.

아이템 22. 인터페이스는 타입을 정의하는 용도로만 사용하라

  • 인터페이스는 자신을 구현한 클래스의 인스턴스를 참조할수 있는 타입역할만 하도록 하자.
    • 이 지침에 맞지 않는 것. 상수 인터페이스 → 차라리 유틸 클래스에 담아 공개해!

    • 지침 위반하는 예시.

      public interface PhysicalConstants {
          // 아보가드로 수 (1/몰)
          static final double AVOGADROS_NUMBER = 6.022_140_857e23;
          // 볼츠만 상수 (J/K)
          static final double BOLTZMANN_CONSTANT = 1.380_648_52e-23;
          // 전자 질량(kg)
          static final double ELECTRON_MASS = 9.109_383_56e-31;
      }

아이템 23. 태그 달린 클래스보다는 클래스 계층구조를 활용하라

  • 태그에 따라서 어떤 필드는 쓰고, 뭐는 안쓰고, 이럴때 는 안쓰던거 쓰고, 쓰던거 안쓰고..
  • 문제 있다
    • 계층 구조로 리팩터링 해라!!

태그 달린 클래스를 클래스 계층구조로 바꾸는 방법

  • 계층구조의 root가 될 추상 클래스를 정의한다
  • 태그 값에 따라 동작이 달라지는 메서드들을 루트 클래스의 추상 메서드로 선언한다
  • 태그 값에 상관없이 동작이 일정한 메서드들을 루트 클래스에 일반 메서드로 추가한다
  • 모든 클래스에서 공통으로 사용하는 데이터 필드도 루트 클래스로 올린다
  • 루트 클래스를 확장한 구체 클래스를 의미별로 하나씩 정의한다

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

  • static 멤버 클래스
    • 다른 클래스 안에 선언되며, 외부 클래스의 private 멤버에도 접근할 수 있다는 점이 일반 클래스와 다른 특징이다.
  • non-static 멤버 클래스 (비정적) 멤버 클래스
    • 바깥 클래스의 인스턴스와 암묵적으로 연결된다. 바깥 인스턴스의 메서드를 호출하거나 참조를 가져올 수 있다.
    • 개념상 중첩 클래스의 인스턴스가 바깥 인스턴스와 독립적으로 존재할 수 있다면 정적 멤버 클래스로 만들어야 한다.
    • 바깥 인스턴스로의 숨은 외부 참조를 갖게 되므로, 시간과 공간이 소비된다. 가비지 컬렉션이 바깥 클래스의 인스턴스를 수거하지 못는 메모리 누수가 생길 수도 있다.
    • 이런 목적이 아니면 정적 멤버 클래스로..!
  • 익명 클래스
  • 지역 클래스

아이템 25. 톱레벨 클래스는 한 파일에 하나만 담으라

  • 말그대로 다. 컴파일러가 무엇을 언제 컴파일 하냐에 따라 뱉는 오류가 다를수가 있다.
profile
SMART https://github.com/dongseoki?tab=repositories

0개의 댓글