분류 전체보기
-
Item 24: Favor static member classes over nonstatic독서/Effective Java 2021. 12. 26. 15:15
멤버 클래스는 되도록 static으로 만들어라 중첩 클래스(Nested Class)? 다른 클래스 안에 정의된 클래스로 자신을 감싼 바깥 클래스에서 쓰여야 하며, 그 외의 쓰임새에서는 톱레벨 클래스로 변경해서 사용한다. 중첩 클래스의 종류 정적 멤버 클래스 (비정적) 멤버 클래스 익명 클래스 지역 클래스 정적 멤버 클래스 바깥 클래스와 함께 쓰일 때만 유용한 public 도우미 클래스로 쓰인다. 바깥 클래스의 private member에 접근 가능하다. 다른 static member fields와 동일한 접근 규칙을 적용받는다. 예를 들어, private으로 선언이 되어 있다면 바깥 클래스 외에는 접근할 수 없다. 정적 멤버 클래스 vs 비정적 멤버 클래스 가장 드러나는 차이점은 static이 붙고 안붙..
-
Item 23: Prefer class hierarchies to tagged classes독서/Effective Java 2021. 12. 26. 15:14
태그 달린 클래스보다는 클래스 계층구조를 활용하라 클래스 계층 구조를 활용하지 않고, 상태를 활용해서 개발된 클래스들은 다음과 같다. class Figure { enum Shape { RECTANGLE, CIRCLE }; // Tag field - 해당 Figure의 모양을 나타냄. final Shape shape; // 직사각형일 경우에만 사용 double length; double width; // 원일 경우에만 사용 double radius; // 원을 위한 생성자 Figure(double radius) { shape = Shape.CIRCLE; this.radius = radius; } // 직사각형을 위한 생성자 Figure(double length, double width) { shape = ..
-
Item 22: Use interfaces only to define types독서/Effective Java 2021. 12. 26. 13:49
인터페이스는 타입을 정의하는 용도로만 사용하라 인터페이스는 구현 클래스의 인스턴스를 참조할 수 있는 타입 역할, 어떤 기능을 수행할 수 있는 지 알려주는 역할로 존재한다. 하지만, 그 외의 용도로 사용하려는 경우도 존재하는데, 대표적으로는 상수 인터페이스(constant interface)가 존재한다. 해당 인터페이스는 method 없이 static final 필드로만 가득 차 있는 인터페이스를 의미한다. // Constant interface antipattern - do not use! public interface PhysicalConstants { // Avogadro's number (1/mol) static final double AVOGADROS_NUMBER = 6.022_140_857e23..
-
Item 21: Design interfaces for posterity독서/Effective Java 2021. 12. 26. 03:51
인터페이스는 구현하는 쪽을 생각해 설계하라. 인터페이스에 새로운 메서드를 추가한다면? Java 8 이전까지는 인터페이스에 메서드를 추가하기 위해서는 해당 인터페이스를 구체화하는 모든 클래스에서 이를 구현하고 있어야 했어서 기존 구현체를 깨트리지 않고는 인터페이스에 메서드를 추가할 방법이 존재하지 않았다. Java 8[JLS 9.4]부터는 "default method"라는 개념이 도입되어 구체화 클래스에서 따로 구현하지 않아도 default method를 사용하면 되지만, 그렇다고 해서 인터페이스에 메서드를 추가할 때의 위험이 사라지는 것은 아니다. 디폴트 메서드를 사용한다고 해도 완벽하게 기존 클래스, 새로 구현할 클래스와 연동 가능하리란 보장은 없다. 즉, 생각할 수 있는 모든 상황에서 불변식을 해치지..
-
Item 20: Prefer interfaces to abstract classes독서/Effective Java 2021. 12. 19. 17:10
추상 클래스보다는 인터페이스를 우선하라 Java에는 다중 구현을 허용하는 유형을 정의하는 메커니즘은 인터페이스와 추상 클래스다. Java 8[JLS 9.4.3]에서 인터페이스에 대한 default 메소드가 도입된 이후로 두 메커니즘 모두 일부 인스턴스 메소드에 대한 구현을 제공할 수 있다. 추상 클래스 vs 인터페이스 추상 클래스에 의해 정의된 유형을 구현하려면 클래스가 추상 클래스의 하위 클래스여야 한다는 것이다. Java는 단일 상속만 허용하기 때문에 추상 클래스에 대한 이러한 제한은 유형 정의로서의 사용을 심각하게 제한한다. 모든 필수 메서드를 정의하고 일반 규약을 준수하는 모든 클래스는 클래스 계층 구조에서 클래스가 있는 위치에 관계없이 인터페이스를 구현할 수 있다. 인터페이스 기존 클래스를 쉽게..
-
Item 19: Design and document for inheritance or else prohibit it독서/Effective Java 2021. 12. 19. 16:17
상속을 고려해 설계하고 문서화하라. 그러지 않았다면 상속을 금지하라. 효과 문서화 클래스는 메서드 재정의의 효과를 정확하게 문서화해야 한다. 클래스는 재정의 가능한 메서드를 호출할 수 있는 모든 상황을 문서화해야 한다. JavaDoc 태그인 @implSpec를 사용하면 API 문서에 "Implementation Requirements" 절(내부 동작 방식 설명)을 생성해준다. 이 문서는 iterator 메서드를 재정의하면 remove 메서드의 동작에 영향을 주고, 또한 iterator 메서드가 반환하는 Iterator의 동작이 remove 메서드의 동작에 어떻게 영향을 미치는지 정확하게 설명한다. Hook 안전하게 하위 분류될 수 있도록 클래스를 문서화하려면 지정되지 않은 상태로 두어야 하는 구현 세부 ..
-
Item 18: Favor composition over inheritance독서/Effective Java 2021. 12. 19. 16:16
상속보다는 컴포지션을 사용하라. 상속은 코드 재사용을 달성하는 강력한 방법이지만 항상 최선은 아니다.부적절하게 사용하면 취약한 소프트웨어로 이어진다. 메서드 호출과 달리 상속은 캡슐화를 위반한다. 즉, 하위 클래스는 적절한 기능을 위해 상위 클래스의 구현 세부 정보에 의존한다. 상위 클래스의 구현은 릴리스마다 변경될 수 있으며 변경될 경우 코드가 건드리지 않았더라도 하위 클래스에 영향이 가고, 결과적으로 하위 클래스는 상위 클래스의 작성자가 확장할 목적으로 특별히 설계하고 문서화하지 않는 한 상위 클래스와 함께 진화해야 한다. package com.tistory.povia.effectivejava.item18; import java.util.Collection; import java.util.HashSe..
-
Item 17: Minimize mutability독서/Effective Java 2021. 12. 19. 14:11
변경 가능성을 최소화하라. 불변 클래스? 불변 클래스는 단순히 인스턴스를 수정할 수 없는 클래스로, 각 인스턴스에 포함된 모든 정보는 Object의 수명 동안 고정되기에 변경 사항을 파악할 수 없다. Java 플랫폼 라이브러리에는 String, boxed 프리미티브 클래스, BigInteger 및 BigDecimal을 비롯한 많은 변경할 수 없는 클래스가 이미 존재한다. 변경 불가능한 클래스는 변경 가능한 클래스보다 설계, 구현 및 사용에 용이하고 오류가 덜 발생하고 더 안전하다. 불변 클래스 생성의 규칙 객체의 상태를 수정하는 메서드(변경자)를 제공하지 않는다. 클래스를 확장할 수 없는지 확인한다. 부주의하거나 악의적인 서브클래스가 Object의 상태가 변경된 것처럼 행동하여 클래스의 불변 동작을 손상..