본문 바로가기
728x90

공부/이펙티브자바33

[이펙티브자바]item 24.멤버 클래스는 되도록 static으로 만들라. 중첩 클래스는 4 가지가 있다. 이중 2가지 정도만 살펴보면될듯, 정적 멤버 클래스 바깥 클래스와 함께 쓰일 때만 유용한 public 도우미 클래스 outer class 와 별개라 생각하면 될듯 비정적 멤버 클래스 바깥 클래스와 암묵적으로 연결된다. 멤버 클래스에서 바깥 인스턴스를 참조할 필요가 없다면 무조건 정적 멤버 클래스로 만들자 익명 클래스 람다를 지원하기전에 즉석에서 작은 함수 객체나 처리 객체를 만들 때 사용. 쓰이는 시점과 동시에 인스턴스가 만들어진다. 지역 클래스 가장 드물게 사용되며, 지역 변수를 사용하는 곳이면 어디든 정의해 사용할 수 있다. public class OuterClass { private static int outerVariable = 20; private int vari.. 2023. 2. 8.
[이펙티브자바]item 23.태그 달린 클래스보다는 클래스 계층구조를 활용하라. 태그 클래스란 특정 기능을 구현하기 위해 클래스에 태그값을 추가하여 사용하는 클래스를 의미한다. 태그란? 특별한 종류의 식별자, 보통 추가 정보를 제공하거나 선언의 동작을 변경하기 위해 선언에 나타낸다. 단순 키워드일 수도 있다. 태그의 단점은 많으므로(장황하고, 오류를 내기쉽고, 비효율 등등) 계층구조(상속)을 사용하여 리팩터링을 해보거나 쓰자. 2023. 2. 6.
[이펙티브자바]item 22.인터페이스는 타입을 정의하는 용도로만 사용하라. 인터페이스는 자신을 구현한 클래스의 인스턴스를 참조할 수 있는 타입 역할을 한다. 상수 인터페이스 같은 경우는 잘못 사용된 예이다. 클래스 내부에서 사용하는 상수는 외부 인터페이스가 아니라 내부 구현에 해당한다. 이러한 경우 몇가지 추천 방법이 있는데 특정 클래스나 인터페이스와 강하게 연관된 상수라면 해당 클래스나 인터페이스에 직접 추가하자. 열거 타입으로 나타내기 적합한 상수라면 열거 타입으로 만들자. 인스턴스화 할 수 없는 유틸리티 클래스에 담아 공개하자 public class PhysicalConstants { private PhysicalConstants() { } // 인스턴스화 방지 public static final double AVOGADROS_NUMBER = 6.022_140_857e23.. 2023. 2. 6.
[이펙티브자바]item 21.인터페이스는 구현하는 쪽을 생각해 설계하라. 인터페이스에 디폴트 메서드를 선언하면, 해당 메서드를 재정의하지 않은 모든 클래스에서 디폴트 구현이 쓰이게 된다. 자바 8 전에는 기존 구현체를 깨뜨리지 않고 인터페이스에 메서드를 추가할 방법이 없었다. 인터페이스에 새로운 메서드 추가는 절대로 없다라고 가정하였으며 디폴트 메서드로 추가하는 길이 열렸지만 기존 구현체들과 매끄럽게 연동되리라는 보장은 없다. 디폴트 메서드는 구현 클래스에 대해 아무것도 모른 채 합의 없이 무작정 "삽입"될 뿐. 디폴트 메서드는 컴파일이 성공하더라도 기존 구현체에 런타임 오류를 일으킬 수 있다. interface MarkerInterface { default void hello() { System.out.println("MarkerInterface.hello"); } } cl.. 2023. 2. 6.
[이펙티브자바]item 20.추상 클래스보다는 인터페이스를 우선하라. 자바 8부터는 인터페이스도 디폴트 메서드를 제공할 수 있다. 기존 클래스에서도 손쉽게 새로운 인터페이스를 구현해넣을 수 있다. 인터페이스로는 계층구조가 없는 타입 프레임워크를 만들 수 있다. Singer, Songwiter 의 인터페이스가 있을시 이 두가지를 받은 SingerSongwriter 를 다중 상속 받아 새로운 인터페이스를 만들 수 있다. 디폴드 메서드를 제공해 프로그래머들의 일감을 덜어줄 수 있다. 이럴경우 item19 처럼 @impleSpec 자바독 태그를 붙여 문서화를 하자. 인터페이스와 추상 골격 구현 클래스를 함께 제공하는 식으로 인터페이스와, 추상 클래스의 장점을 모두 취하는 방법도 있다. 인퍼페이스의 강제 구현 요구와 추상 클래스의 기본 구현 제공을 동시에 제공할 수 있기 때문이다... 2023. 2. 3.
[이펙티브자바]item 19.상속을 고려해 설계하고 문서화하라.그러지 않았다면 상속을 금지하라. 상속용 클래스는 재정의할 수 있는 메서드들을 내부적으로 어떻게 이용하는지 문서로 남겨야 한다. 재정의? => public과 protected 메서드 중 final 이 아닌 모든 메서드를 뜻함 @impleSpec 어노테이션으로 자바독을 만들 수 있다. API 의 문서를 만들때는 "어떻게"가 아닌 "무엇"을 하는지 설명하는거에 대비하여 상속을 위한 내부클래스의 문서화는 상당히 내부구조까지 설명을 해야한다. 이는 캡슐화가 이미 깨졌고 내부 구현을 모르면 오작동의 위험이 있기 때문이다. 클래스의 내부 동작 과정 중간에 끼어들 수 있는 훅을 잘 선별하여 protected 메서드 형태로 공개해야 할 수도 있다. 어떤 클래스를 protected 로 노출해야할지 결정하는 방법은 직접 하위 클래스를 3개 정도 만들어 보.. 2023. 2. 3.
[이펙티브자바]item 18.상속보다는 컴포지션을 사용하라. 상속은 많은 문제가 발생할 수 있다. 패키지 경계를 넘어, 즉 다른 패키지의 구체 클래스를 속하는 일은 위험하다. 상속은 캡슐화를 깨뜨린다. 깨뜨린다보다 상속을 받은 자식 클래스가 상위 클래스의 private 멤버에 접근할 수 있기때문에 캡슐화의 의도와 달리 구현이 공개 될 수 있게 된다. 상위 클래스의 구현에따라 동작에 이상이 생길 수 있다. 이를 해결하기 위해 컴포지션(Composition)을 사용하라는 얘기이다. 컴포지션: 기존 클래스를 확장하는대신, 새로운 클래스를 만들고, private 필드로 기존 클래스의 인스턴스를 참조하게 한다. 기존 클래스의 대응하는 메서드를 호출해 그 결과를 반환한다. 이를통해 기존 클래스의 구현이 바뀌거나, 새로운 메서드가 생기더라도 아무런 영향이 받지 않는다. 119.. 2023. 2. 2.
[이펙티브자바]item 17.변경 가능성을 최소화하라 불변 클래스를 쓰면 좋은점은? 불변 클래스는 가변 클래스보다 설계하고 구현하고 사용하기 쉬우며, 오류가 생길 여지도 적고 훨씬 안전하다 클래스를 불변으로 만들려면 다음 다섯 가지 규칙을 따른다. 객체의 상태를 변경하는 메서드(변경자)를 제공하지 않는다 setter 를 열지 않는다. 클래스를 확장할 수 없도록 한다. final 로 상속을 막자 모든 필드를 final 로 선언한다. 모든 필드를 private 로 선언한다. 자신 외에는 내부의 가변 컴포넌트에 접근할 수 없도록 한다. 클래스 내부에 가변 객체가 있다면 접근할 수 없도록 하고, 혹시라도 접근을 허용한다면 방어적 복사를 통해 제공해주오, 실수를 하더라도 원본은 그대로로 유지하도록 하자. 불변 클래스의 장점 함수형 프로그래밍에 적합 불편객체는 단순하.. 2023. 1. 31.
[이펙티브자바]item 16.public 클래스에서는 public 필드가 아닌 접근자 메서드를 사용하라 class Point { public int x; public int y; } 해당 클래스는 데이터 필드에 직접 접근할 수 있어 캡슐화의 장점을 제공하지 못한다. API 를 수정하지 않고는 내부 표현을 바꿀 수 없고 내부 필드명을 봐꾸더라도 점진적으로 변경할 수 있다. 불변식을 보장할 수 없으며 외부에서 필드에 접근할 때 부수 작업을 수행할 수 없다. 메서드를 통해 접근하면 내부 작업을 수행 후 return 할 수 있다. package-private 클래스 에서도 데이터 필드를 노출해도 하등의 문제가 없다 맞는 말일 수도있는데, 그래도 필드에 직접 접근보다는 메서드를 통해 접근하도록 하자. 2023. 1. 31.
728x90