이펙티브자바

    [Effective Java] 상속을 고려해 설계하고 문서화하라

    상속용 클래스는 내부 구현을 문서로 남겨야 한다. '외부' 클래스를 사용한다는 것은 프로그래머에게 통제권이 없어 언제 어떻게 변경될지 모른다는 의미를 갖는다. 따라서 상속용 클래스를 만들 때는 메서드를 재정의하면 어떤 일이 일어나는지 정확히 정리하여 문서로 남겨야 한다. (public, protected 메서드 중 final이 아닌 모든 메서드) => 어떤 순서로 호출하는지, 각각의 호출 결과가 이어지는 처리에 어떤 영향을 주는지 등 Implementation Requirements API 문서의 메서드 설명에 있는 문구로, 메서드의 내부 동작 방식을 설명하는 곳이다. @implSpec태그를 붙여주면 자바독 도구가 생성해준다. 주의 상속용 클래스의 생성자는 어떤 방식으로든 재정의 가능 메서드를 호출하면 ..

    [Effective Java] 상속보다는 컴포지션을 사용하라

    상속을 사용하면 위험한 이유 (구현 상속) 상위 클래스에서 제공하는 메서드 구현이 바뀐다면 하위 클래스의 로직에도 영향을 줄 수 있다. 상위 클래스에 기능이 추가된 경우 새로운 메서드를 하위 클래스에도 정의해 주어야 한다. 이러한 문제를 해결하기 위해 컴포지션을 사용할 수 있다. 컴포지션 전달 클래스 : 새로운 클래스를 만들고 기존 클래스의 인스턴스를 참조하는 클래스 public class ForwardingSet implements Set { private final Set s; public ForwardingSet(Set s) { this.s = s; } public void clear() { s.clear(); } public boolean contains(Object o) { return s.co..

    [Effective Java] 변경 가능성을 최소화하라

    불변 클래스 불변 클래스란 간단히 말해 그 인스턴스의 내부 값을 수정할 수 없는 클래스다. 불변 클래스는 가변 클래스보다 설계하고 구현하고 사용하기 쉬우며, 오류가 생길 여지도 적고 훨씬 안전하다. 불변 클래스를 만드는 규칙 객체의 상태를 변경하는 메서드를 제공하지 않는다. 클래스를 확장할 수 없도록 한다. => 상속을 막는 대표적인 방법은 클래스를 final로 선언하는 것이다. => 생성자를 모두 private으로 만들고 정적 팩터리를 제공하는 방법도 있다. => 다음 코드에서는 PhoneNumber를 상속하고 name필드를 바꿀 수 있는 변경 메서드를 정의함으로써 불변이 아닌 경우의 수를 제공하게 된다. // 불변 클래스를 의도하고 만들었다고 가정하자. public class PhoneNumber {..

    [Effective Java] public 클래스에서는 public 필드가 아닌 접근자 메서드를 사용하라

    퇴보한 클래스 class Point { public double x; public double y; } 다음과 같은 클래스는 필드에 직접 접근할 수 있으니 캡슐화의 이점을 제공하지 못한다. 이 클래스는 API를 수정하지 않고는 내부 표현을 바꿀 수 없고, 불변식을 보장할 수 없으며, 유효성 검사와 같은 부가 작업이 어려워진다. private필드와 접근자(getter)를 추가한다. 객체 지향 프로그래밍에서는 필드를 모두 private으로 바꾸고 public 접근자를 추가하는 것이 좋다. class Point { private double x; private double y; public Point(double x, double y) { this.x = x; this.y = y; } public double..

    [Effective Java] 클래스와 멤버의 접근 권한을 최소화하라

    잘 설계된 컴포넌트를 설계하기 위해서는 클래스 내부 데이터와 내부 구현 정보를 외부 컴포넌트로부터 잘 숨겨야 한다. 즉, 모든 내부 구현을 완전히 숨김으로서, 구현과 API를 깔끔히 분리해야 한다. 정보 은닉(캡슐화) 정보 은닉(캡슐화)라고 하는 이 개념은 소프트웨어 설계의 근간이 되는 원리다. 오직 API를 통해서만 서로 소통하며 내부적으로 어떻게 동작하는지는 신경쓰지 않는다. 정보 은닉의 장점 여러 컴포넌트를 병렬로 개발할 수 있기 때문에 개발 속도를 높일 수 있다. 각 컴포넌트를 더 빨리 파악하여 디버깅하기 쉽고, 다른 컴포넌트로 교체하는 부담도 적기 때문에 시스템 관리 비용이 낮다. 정보 은닉 자체가 성능을 높여주지는 않지만, 성능 최적화에 도움을 준다. -> 해당 컴포넌트만 최적화할 수 있다. ..