백수의 개발
-
Item 22. 인터페이스는 타입을 정의하는 용도로만 사용하라백수의 개발/이펙티브 자바 2019. 10. 8. 12:00
인터페이스는 자신을 구현한 클래스의 인스턴스를 참조할 수 있는 타입 역할을 한다. 즉, 자신의 인스턴스로 무엇을 할 수 있는지를 클라이언트에 얘기해주는 것이다. 따라서 인터페이스는 오직 이 용도로만 사용해야 한다. 이 지침에 맞지 않는 예로 상수 인터페이스라는 것이 있다. 이는 상수를 뜻하는 static final 필드로만 가득 찬 인터페이스를 말한다. 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)..
-
Item 21. 인터페이스는 구현하는 쪽을 생각해 설계하라백수의 개발/이펙티브 자바 2019. 10. 7. 12:13
인터페이스 메서드 추가 자바 8 전에는 기존 구현체를 깨뜨리지 않고는 인터페이스에 메서드를 추가할 방법이 없었다. 기존 인터페이스에 메서드를 추가했을 때, 기존 구현체에 이미 존재할 가능성이 아주 낮기때문에 정의되지 않은 추가 된 메서드로 인해 컴파일 오류가 발생한다. 자바 8에 와서 기존 인터페이스에 메서드를 추가할 수 있도록 디폴트 메서드가 나왔다. 그러나 모든 기존 구현체들과 매끄럽게 연동되리라는 보장은 없다. 게다가 생각할 수 있는 모든 상황에서 불변식을 해치지 않는 디폴트 메서드를 작성하기란 어려운 법이다. Collection 인터페이스에 추가된 removeIf 메서드를 보자. default boolean removeIf(Predicate
-
Item 20. 추상 클래스보다는 인터페이스를 우선하라백수의 개발/이펙티브 자바 2019. 10. 6. 12:07
추상 클래스와 인터페이스 자바가 제공하는 다중 구현 메커니즘은 인터페이스와 추상 클래스 두가지가 있다. 둘의 가장 큰 차이는 추상 클래스가 정의한 타입을 구현하는 클래스는 반드시 추상 클래스의 하위 클래스가 되어야 한다는 것이다. 그러나 인터페이스는 어떤 클래스를 상속했든 같은 타팁으로 취급된다. 그 결과 기존 클래스에 새로운 인터페이스를 구현하기 편하다. 인터페이스의 장점 1. (*)믹스인(mixin) 정의에 안성맞춤이다. 믹스인이란? 클래스가 자신의 본래타입에 추가하여 구현할 수 있는 타입 2. 계층구조가 없는 타입 프레임워크를 만들 수 있다. 가수(Singer), 작곡가(Songwriter), 작곡가겸 가수(SingerSongwriter) 예시를 통해 인터페이스의 두번째 장점에 대해 살펴보자. 만약..
-
Item 19. 상속을 고려해 설계하고 문서화하라. 그러지 않았다면 상속을 금지하라백수의 개발/이펙티브 자바 2019. 10. 5. 12:03
상속을 위한 문서화 상속용 클래스는 재정의할 수 있는 메서드들을 내부적으로 어떻게 이용하는지 남겨야한다. 클래스의 API로 공개된 메서드에서 클래스 자신의 또 다른 메서드를 호출할 수 있다. 이 때 호출하는 메서드가 재정의 가능 메서드라면 그 사실을 호출하는 메서드의 API 설명에 적시해야 한다. 덧붙여 어떤 순서로 호출하는지, 각각의 호출 결과가 이어지는 처리에 어떤 영향을 주는지도 담아야 한다. * API 문서의 메서드 설명 끝에 "Implementation Requirements"라고 되어 있다면, 그 메서드의 내부 동작 방식을 설명하는 것이다. 아래는 java.util.AbstactCollection API문서의 remove 메서드이다. 해당 메서드의 기능에 대해 우선 이야기를 하고, implem..
-
Item 18. 상속보다는 컴포지션을 사용하라백수의 개발/이펙티브 자바 2019. 10. 4. 12:42
상속 상속은 코드를 재사용하는 강력한 수단이다. 하지만, 잘못 사용하면 오류를 내기 쉬운 소프트웨어를 만들게 된다. 이 장에서의 상속은 클래스가 다른 클래스를 확장하는 구현 상속을 말하는 것이며, 클래스가 인터페이를 구현하거나 인터페이스가 다른 인터페이스를 확장하는 인터페이스 상속에 대한 이야기는 아니다. 상위 클래스는 릴리스마다 내부 구현이 달라질 수 있으며, 그 여파로 코드 한 줄 건드리지 않은 하위 클래스가 오작동할 수 있다. 오류 가능성이 있는 상속 아래 HashSet을 상속하는 InstrumentedHashSet에 대한 코드를 살펴보자. public class InstrumentedHashSet extends HashSet { private int addCount = 0; public Instr..
-
Item 17. 변경 가능성을 최소화하라백수의 개발/이펙티브 자바 2019. 10. 2. 16:38
불변 클래스 인스턴스의 내부 값을 수정할 수 없는 클래스이다. 불변 클래스의 인스턴스는 객체가 생성되는 시점에 초기화 되고 소멸될 때까지 절대 달라지지 않는다. 불변 클래스는 가변 클래스보다 설계하고 구현하기 쉽다. 불변 클래스는 사용하기 쉬우며, 오류가 생길 여지도 적고 훨씬 안전하다. 불변 클래스를 만드는 5가지 규칙 객체의 상태를 변경하는 메서드(변경자)를 제공하지 않는다. 클래스를 확장할 수 없도록(상속을 막는다) 한다. 클래스를 final로 선언 모든 생성자를 private로 선언, 생성자 정적 팩터리 메서드를 제공 모든 필드를 final로 선언한다. (스레드 안전함) 모든 필드를 private로 선언한다. 자신 외에는 내부의 가변 컴포넌트에 접근 할 수 없도록 한다. 객체의 참조를 얻을 수 없..
-
Item 16. public 클래스에서는 public 필드가 아닌 접근자 메서드를 사용하라백수의 개발/이펙티브 자바 2019. 10. 1. 12:31
class Point{ public double x; public double y; } 위와 같은 클래스는 데이터 필드에 직접 접근할수 있으니 캡슐화의 이점을 제공하지 못한다.(퇴보한 클래스) API를 수정하지 않고는 내부 표현을 바꿀 수 없다. 불변식을 보장할 수 없다. 외부에서 필드에 접근할 때 부수 작업을 수행할 수 없다. 따라서, 필드들을 모두 private로 바꾸고 public 접근자(getter)를 추가한다. 접근자와 설정자 제공 class Point{ private double x; private double y; public Point(double x, double y){ this.x = x; this.y = y; } public double getX() { return x; } publi..
-
Item 15. 클래스와 멤버의 접근 권한을 최소화하라백수의 개발/이펙티브 자바 2019. 9. 30. 12:00
잘 설계된 컴포넌트는 모든 내부 구현을 완벽히 숨겨, 구현과 API를 깔끔히 분리한다. 오직 API를 통해서만 다른 컴포넌트와 소통하며, 서로의 내부 동작 방식에는 전혀 개의치 않는다. 정보 은닉, 혹은 캡슐화라고 하는 이 개념은 소프트웨어 설계의 근간이 되는 원리다. 정보 은닉의 장점 시스템 개발 속도를 높인다. 여러 컴포넌트를 병렬로 개발할 수 있기 때문이다. 시스템 관리 비용을 낮춘다. 각 컴포넌트를 더 빨리 파악하여 디버깅할 수 있고, 다른 컴포넌트로 교체하는 부담도 적기 때문이다. 정보 은닉 자체가 성능 향상을 시키지는 않지만, 성능 최적화에 도움을 준다. 다른 컴포넌트에 영향을 주지 않고 해당 컴포넌트만 최적화할 수 있도록 하기 때문이다. 소프트웨어의 재사용성을 높인다. 외부에 거의 의존하지 ..