본문 바로가기

책/effective java29

[effective java] item 24. 멤버 클래스는 되도록 static으로 만들라 결론 중첩 클래스에는 네 가지가 있으며, 각각의 쓰임이 다릅니다. 메서드 밖에서도 사용해야 하거나, 안에 정의하기에 너무 길다면 멤버 클래스로 만듭니다. 멤버 클래스의 인스턴스 각각이 바깥 클래스를 참조한다면 비정적으로, 그렇지 않으면 정적으로 만듭시다. 중첩 클래스가 한 메서드 안에서만 쓰이면서 그 인스턴스를 생성하는 지점이 단 한곳이고 해당 타입으로 쓰기에 적합한 클래스나 인터페이스가 이미 있다면 익명 클래스로 만들고, 그렇지 않으면 지역 클래스로 만듭시다. 설명 중첩 클래스(nested class)란 다른 클래스 안에 정의된 클래스를 말합니다. 중첩 클래스는 자신을 감싼 바깥 클래스에서만 쓰여야 합니다. 중첩 클래스의 종류 정적 멤버 클래스 (비정적) 멤버 클래스 익명 클래스 지역 클래스 이번 아이.. 2023. 8. 21.
[effective java] item 23. 태그 달린 클래스보다는 클래스 계층구조를 활용하라 결론 태그 달린 클래스를 써야 하는 상황은 거의 없습니다. 기존 클래스나 새로운 클래스를 작성하는 데 태그 필드가 등장한다면, 태그를 없애고 계층구조로 대체하는 방법을 생각해봅시다. 설명 태그 달린 클래스? 두 가지 이상의 의미를 표현할 수 있으며, 그중 현재 표현하는 의미를 태그 값으로 알려주는 클래스가 있습니다. 태그 달린 클래스 예시 - 클래스 계층구조보다 훨씬 나쁘다 (p.142) 원과 사각형을 표현할 수 있는 클래스입니다. class Figure { enum Shape { RECTANGLE, CIRCLE }; // 태그 필드 - 현재 모양을 나타낸다. final Shape shape; // 다음 필드들은 모양이 사각형(RECTANGLE)일 때만 쓰인다. double length; double w.. 2023. 8. 21.
[effective java] item 22. 인터페이스는 타입을 정의하는 용도로만 사용하라 결론 인터페이스는 타입을 정의하는 용도로만 사용해야 합니다. 상수 공개용 수단으로 사용하면 안 됩니다. 인터페이스의 대안으로 특정 클래스나 인터페이스와 강하게 연관된 상수의 경우 클래스 및 인터페이스 내부에 상수 선언, 열거 타입 사용, 유틸리티 클래스가 있습니다. 설명 인터페이스는 클래스의 인스턴스를 참조할 수 있는 타입 역할을 말합니다. 인터페이스는 오직 이러한 타입을 정의하는 용도로만 사용해야 합니다. 인터페이스의 잘못된 사용 : 상수 인터페이스 이 지침에 맞지 않는 예로 상수 인터페이스라는 것이 있습니다. 상수 인터페이스란 메서드 없이, 상수를 뜻하는 static final 필드로만 가득 찬 인터페이스를 말합니다. 그리고 이 상수들을 사용하려는 클래스에서는 정규화된 이름을 쓰는 걸 피하고자 그 인.. 2023. 8. 21.
[effective java] item 21. 인터페이스는 구현하는 쪽을 생각해 설계하라 결론 자바 8에서 디폴트 메서드가 등장하면서, 인터페이스에 새 메서드를 추가하는 일이 비교적 간편해졌습니다. 하지만, 디폴트 메서드를 사용함으로써 위험이 완전히 사라진 것은 아닙니다. 새 인터페이스를 생성한다면, 최대한 많은 구현과 이를 사용하는 클라이언트를 만들고 테스트를 거침으로써 결함이 없는지를 판단한 후에 릴리스를 해야 합니다. 릴리스한 후라도 결함을 수정하는 게 가능한 경우도 있겠지만, 절대 그 가능성에 기대서는 안 됩니다. 설명 자바 7 까지의 세상에서는 모든 클래스가 "현재의 인터페이스에 새로운 메서드가 추가될 일은 영원히 없다" 라고 가정하고 작성됐습니다. 자바 8에 와서 메서드를 재정의하지 않고 인터페이스에 새 메서드를 추가할 수 있도록 디폴트 메서드가 등장했지만, 위험이 완전히 사라진 .. 2023. 8. 21.
[effective java] item 20. 추상 클래스보다는 인터페이스를 우선하라 결론 일반적으로 다중 구현용 타입으로는 추상 클래스보다 인터페이스가 가장 적합합니다. 복잡한 인터페이스라면 구현하는 수고를 덜어주는 골격 구현을 함께 제공하는 방법을 꼭 고려해봅시다. 골격 구현은 '가능한 한' 인터페이스의 디폴트 메서드로 제공하여 그 인터페이스를 구현한 모든 곳에서 활용하도록 하는 것이 좋습니다. '가능한 한' 이라고 한 이유는, 인터페이스에 걸려 있는 구현상의 제약 때문에 골격 구현을 추상 클래스로 제공하는 경우가 더 흔하기 때문입니다. 설명 자바가 제공하는 다중 구현 매커니즘은 인터페이스와 추상 클래스, 이렇게 두가지입니다. 자바8부터 인터페이스도 디폴트 메서드를 제공할 수 있게 되어 이제는 두 매커니즘 모두 인스턴스 메서드를 구현 형태로 제공할 수 있습니다. 추상 클래스보다 인터페.. 2023. 8. 21.
[effective java] item 18. 상속보다는 컴포지션을 사용하라 결론 상속은 강력하지만 캡슐화를 깨뜨린다는 단점이 있습니다. 대안책으로 컴포지션과 전달을 사용할 수 있습니다. 특히 래퍼 클래스로 구현할 적당한 인터페이스가 있다면 더욱 좋습니다. 핵심 코드 public class CustomHashSetByComposition { private final HashSet hashSet; private int addCount = 0; public CustomHashSetByComposition(HashSet hashSet) { this.hashSet = hashSet; } public boolean add(E e) { addCount++; return hashSet.add(e); } public boolean addAll(Collection c) { return s.con.. 2023. 8. 7.