Effective Java 18

짧은 코멘트와 함께하는 이펙티브 자바) #20 추상 클래스보다는 인터페이스를 우선하라

짧은코멘트 요약을 잘해서 생략. 추상 클래스보다는 인터페이스를 왜 우선해야 하는지 어떤 경우에는 추상 클래스가 효과적일 수 있는지 잘 제시되어 있다. 추상 클래스보다는 인터페이스를 우선하라 자바가 제공하는 다중 구현 메커니즘은 인터페이스와 추상 클래스 두 가지이다. 둘의 가장 큰 차이는 추상 클래스가 정의한 타입을 구현하는 클래스는 반드시 추상 클래스의 하위 클래스가 되어야 한다는 점이다. 자바는 단일 상속만 지원하니, 추상 클래스 방식은 새로운 타입을 정의하는 데 제약을 안게 되는 셈이다. 인터페이스를 사용하면 장점이 몇 가지 있다. 기존 클래스에도 손쉽게 새로운 인터페이스를 구현해 넣을 수 있다. 인터페이스는 믹스인 정의에 안성맞춤이다. 인터페이스로는 계층구조가 없는 타입 프레임워크를 만들 수 있다...

짧은 코멘트와 함께하는 이펙티브 자바) #19 상속을 고려해 설계하고 문서화하라. 그러지 않았다면 상속을 금지하라

짧은코멘트 Spring 애플리케이션 개발자가 상속을 할 일은 생각보다 많지 않다. 중복되는 필드가 있는 경우 데이터 구조를 표현하기 위한 정도...? 요즘에는 IDE가 원낙 잘 되어 있어 프로젝트에서 사용하는 모든 클래스에 final을 붙일 필요까지는 없는 것 같다. 같은 팀끼리는 의사소통이 잘 되는 측면도 있고... 몇몇 유틸성 클래스에 private constructor를 잘 달아주는 정도면 충분할 것 같다. 상속을 고려한 설계와 문서화 상속용 클래스를 설계하기란 결코 만만치 않다. 상속용 클래스를 만들려면 클래스 내부에서 스스로를 어떻게 사용하는지 (자기 사용 패턴) 모두 문서로 남겨야 한다. 이때 @implSpec 태그를 사용할 수 있다. 상속과 관련되어 문서화한 것은 그 클래스가 사용되는한 반드..

짧은 코멘트와 함께하는 이펙티브 자바) #18 상속보다는 컴포지션을 사용하라

짧은코멘트 회사 블로그에 기고한 글에서도 살짝 이야기 했지만 상속보다는 합성을 사용하는 것이 훨씬 수월하다. 합성에 익숙해지면 어느덧 extends 보다 implements를 선호하게 될 것이다. 상속보다는 합성을 사용하라 일반적인 구체 클래스를 패키지 경계를 넘어 상속하는 일은 위험하다. 메소드 호출과 달리 상속은 캡슐화를 깨뜨린다. 상위 메소드를 부를때 자기 사용 여부에 따라 의도와 다르게 동작할 수 있다. (자기 사용 : 한 클래스의 퍼블릭 인터페이스에서 같은 클래스 내 다른 퍼블릭 인터페이스를 사용하여 기능을 완성한 것) 또한, 상위 클래스의 한 메소드가 상위 클래스의 다른 메소드를 사용하는 자기 사용 여부는 내부 구현 방식에 해당되기 때문에 다음 릴리스에서 유지될지 알 수 없다. 다음 릴리스에서..

짧은 코멘트와 함께하는 이펙티브 자바) #17 변경 가능성을 최소화하라 (불변객체)

짧은코멘트 아래에 언급된 장점들로 인해 불변 객체는 정말 자주 사용되며 final 키워드에 대해서는 잘 알아두면 좋다. class나 method에서도 간혹 사용할 일이 있기 때문이다. 불변 객체의 연산을 예측하는 것 뿐만 아니라 객체 생성이 제한적이라면 내부에 캐싱해두는 것도 성능상 괜찮은 방법이다. 특히 Enum은 자연스럽게 불변 객체가 되는데 name이나 특정 key를 사용해 Enum 찾을 일이 많다면 캐싱이 권장된다. 변경 가능성을 최소화하라 불변 클래스란 그 인스턴스의 내부 값을 수정할 수 없는 클래스이다. 불변 클래스는 가변 클래스보다 설계하고 구현하고 사용하기 쉬우며, 오류가 생길 여지도 적고 훨씬 안전하다. 불변 클래스는 다섯 가지 규칙을 따라야 한다. 객체의 상태를 변경하는 메소드를 제공하..

짧은 코멘트와 함께하는 이펙티브 자바) #15 클래스와 멤버의 접근 권한을 최소화하라

짧은 코멘트 클래스와 메소드, 그리고 필드의 접근 권한을 적절히 설정하는 일은 단순히 접근할 수 있다 / 없다 뿐 아니라, 코드를 읽는 사람 입장에서, '이 필드는 밖에서도 사용되나?' / '이 코드는 내부에서만 사용되구나'를 유추할 수 있게 해주는 수단이다. 때문에 clean code에 있어 기초적이면서도 중요하다고 생각한다. 가끔 단위 테스트를 작성하기 위해 private method를 public method로 만드는 분들이 계시는데, 그 보다 나은 방법은 default 접근 권한을 사용하는 것이다. 그리고 그 보다 조금 더 나은 방법은 테스트 해야할 부분과 테스트를 해야하지 않을 부분을 명확히 구분하여 외부로 하여금 내부를 테스트 하게 하는 것이다. (lannstark.tistory.com/105..

짧은 코멘트와 함께하는 이펙티브 자바) #14 Comparable을 구현할지 고려하라

짧은 코멘트 Comparable을 생각보다 종종 구현을 하게 된다. 안타깝게 항상 헷갈리는 부분이 있는데 결과가 음수 혹은 양수일때 어떤 것이 앞에 가느냐... 이다 이럴때 해당 객체에 대한 단위 테스트를 깔끔하게 작성해주면 정말 좋다 👍 Comparable을 구현할지 고려하라 compareTo는 Object equals와 유사하다. 다른 점이라곤, compareTo는 단순 동치성 비교에 더해 순서까지 비교할 수 있으며 제네릭 한 것과 Comparable을 구현했다는 것은 그 클래스의 인스턴스들에는 자연적인 순서가 있음을 뜻하는 것이다. Comparable을 구현하면 검색, 극단값 계산, 자동 정렬되는 컬렉션 관리도 쉽게 할 수 있다. 자바 플랫폼 라이브러리의 모든 값 클래스와 열거타입은 Comparab..

짧은 코멘트와 함께하는 이펙티브 자바) #13 clone 재정의는 주의해서 진행하라

짧은 코멘트 Cloneable을 실제로 구현해본 적은 없는 듯 하다. 백엔드 개발자로써 특정 객체에 복제를 해야할 일이 드물기 때문이다. 얕은 복사(shallow copy)와 깊은 복사(deep copy) 차이는 알아두는 것이 좋다. 얕은 복사는 객체 내부에 있는 참조 객체가 복제되지 않는 것이고, 깊은 복사는 객체 내부에 있는 참조 객체까지 복제되는 것이다. clone 재정의는 주의해서 징행하라 Cloneable은 복제해도 되는 클래스임을 명시하는 용도의 믹스인 인터페이스이다. 믹스인 : 클래스가 구현할 수 있는 타입. 믹스인이라 부르는 이유는 실제 클래스가 가지고 있는 주된 기능에 특정 타입을 구현함으로써 선택적인 기능을 혼합하기 때문이다 예시) public interface Comparable { ..

짧은 코멘트와 함께하는 이펙티브 자바) #12 toString을 항상 재정의하라

짧은 코멘트 lombok의 @ToString을 사용하면 Object의 toString을 쉽게 재정의할 수 있다. 모든 객체에 @ToString을 붙일 필요는 없지만, DTO에 붙이는 것은 디버깅시 꽤 유용했던 경험이 많다. toString을 항상 재정의 하라 Object 클래스의 기본 메소드 toString은 클래스이름@해시코드를 반환한다. 때문에 모든 클래스의 toString은 항상 재정의 하는 것이 좋다. 심지어 Object 클래스의 tostring의 규약은 “모든 하위 클래스에서 이 메소드를 재정의하라”이기도 하다. toString은 그 객체가 가진 주요 정보 모두를 반환하는 게 좋다. 또한 toString을 작성할 때 의도를 명확히 밝혀야 한다. 포맷 명시 toString을 구현할 때면 반환값의 ..

짧은 코멘트와 함께하는 이펙티브 자바) #11 equals를 재정의하려거든 hashCode도 재정의하라

짧은 코멘트 equals 관련 코멘트에서 다루었던 것처럼 @EqualsAndHashCode 를 사용할 수 있다. 단, 이때 컬렉션이나 순환참조 객체 등을 @EqualsAndHashCode 대상 필드에 포함시키면 문제가 될 수 있다. IntelliJ 에서 command + N(윈도우는 아마 control + N..?) 을 눌러, equals And hashCode를 자동으로 만들어줄 수 있다. hashCode equals를 재정의한 클래스 모두에서는 hashCode도 재정의 해야 한다 hashCode의 규약 중 일부는 이렇다 - equals 비교에 사용되는 정보가 변경되지 않았다면, 애플리케이션이 실행되는 동안 그 객체의 hashCode 메소드는 몇 번을 호출해도 일관되게 항상 같은 값을 반환해야 한다 -..

짧은 코멘트와 함께하는 이펙티브 자바) #10 equals는 일반 규약을 지켜 재정의하라

짧은 코멘트 1. 테스트를 작성할때 equals를 활용할 수 있다. // 1. getter를 사용하는 방식 Person result = getPerson(); assertThat(result.getName()).isEqualTo("lannstark"); assertThat(result.getAge()).isEqualTo(20); // 2. equals를 사용하는 방식 Person result = getPerson(); assertThat(result).isEqualTo(new Person("lannstark", 20)); 2. lombok의 @EqualsAndHashCode를 이용하면 편리하다. 3. 실무에서 DB Table과 매핑되는 객체에 사용하기에는 다소 어려움이 있다. 필드가 굉장히 많기 때문. ..