참조 :
http://www.infoq.com/articles/API-Design-Joshua-Bloch
http://www.infoq.com/presentations/effective-api-design;jsessionid=E80287C669787CA7AD3F810A3850932B

Public API(아마 인터페이스를 말하는듯)는 영원한거다. 그만큼 신중하게 만들어야 함.

좋은 API 특징. 문서 없이도 잘 이해가 되는 API

API 설계 프로세스

요구사항을 분명히 할 것

모두를 만족 시킬 순 없다. 모두를 똑같이 실망시켜라.
- 실수 할 수도 있다. API를 진화시켜라.

미심쩍은 것은 무조건 빼내라. 나중에 추가하긴 쉽지만, 빼는 건 불가능에 가깝다.

구현에 대한 세부 사항이 API에 영향을 주지 않게 한다.

최소한의 접근성
- default 접근 지시자가 protected보다 엄격하다. 엄하게 구분해놔야 테스트하기 좋다.

작명은 중요하다.
- 마치 영어 문장처럼 읽히는 코드를 작성하라.

문서화 중요하다.
- 모든 클래스, 메소드, 필드, 파라메터, 예외에 대해 문서화하라.

API 성능에 신경써라.
- Dimension Component.getSize() 같은 API는 매번 새로운 mutable한 Dimention 객체를 생성해내서 성능이 안 좋다.

클래스 설계

mutable은 최대한 최소화하라. 되도록이면 immutable.
- Date랑 Calandar 안 좋아. 변할 수 있는데 왜 안 변해. TimerTask 처럼 좀 변하란 말야.

상속은 리스코프 원칙에 맞게 사용할 것
- is-a 관계 일 때만 사용하기.

메소드 설계

모듈이 할 수 있는 걸 고객이 직접 하게 하지 말아라.
- boilerplate 코드 작성할 필요를 없애라.

Principle of least astonishment를 위배하지 말라.
- Thread의 interrpt의 경우 안 좋은 예에 해당한다. 인터럽트 할 때 현재 상태 정보를 클리어 해버린다. 따라서 clearAndInterrupt라고 하는게 낫겠다.

Fail-Fast
- 컴파일 타임에 에러나면 좋고, 실행 중엔 첫 번째 메소드 호출에서 바로 fail하도록..
- Generic 쓰면 컴파일 타입에 타입 체크 할 수 있으니 좋다.

문자열로 데이터 보여주는 API를 제공하라.
- 안그럼 고객이 직접 작성해야 한다.
- StrackTraceElement 객체의 같은 거 좋다.

오버로딩 사용에 신중하라.
- 오버로딩 할 때는 같은 기능을 제공해야 한다.
- TreeSet의 생성자는 안 좋은 예에 해당한다. 넘겨주는 인자에 따라 행위가 다르다.

파라미터와 리턴타입
- float으로 화폐단위 표시하지 말것. 부정확하다.
- 인터페이스 타입을 사용하면 유연하고 성능에좋다.
- 구체적인 타입일 수록 컴파일 타임에 에러를 잡을 수 있다.
- 문자열 보단 특정 타입을 사용할 수 있도록하자. 문자열은 에러 발생할 여지가 많다.(흠.. 문자열을 써야 할 경우엔 해당 문자열을 상수화해서 쓰면 괜찮지 않을까.)

너무 긴 매개변수 리스트는 피하라.
- 메소드를 나누던가, 헬퍼 클래스를 만들어서 줄여라.

에러 발생 시킬 반환값을 피하라.
- null말고, 비어있는 리스트나 배열을 반환하라.

예외로 흐름 제어 하지 말아라.
- 제어문으로 해라~. 예외는 예외적인 상황일때 그것을 알려주기 위해 사용하라.

언체크드 익셉션을 선호하라.
- checked exception - 사용자가 반드시 복구해야 할 때 사용
- unchecked exception - 프로그래밍 에러

API 설계 리팩토링하기

Vector의 indexOf 메소드
- Vector, List
- ThreadLocal의 string -> Key