2017년 12월 18일 월요일

JAVA API 디자인, 7-8장

http://charlie0301.blogspot.kr/2017/12/java-api.html
http://charlie0301.blogspot.kr/2017/12/java-api-5-6.html

책이 API 디자인 외에 한번쯤 library, framework을 고민한다면 읽어 볼 만함.
일부만 추려서 적었지만 책에는 더 좋은 내용이 자~알 설명 되어 있음.

------------------------------------------------------------------------------------
Chapter 7 :  모듈화 아키텍처를 사용하라

1. 모듈화 설계의 유형

라이브러리
모듈화 라이브러리들을 사용 시 구현이 중복일 수 있고 이 때 최신 API JAR만 로드 되어 링크 될 수 있도록 해야 함.
모듈화 라이브러리의 경우 각 모듈의 구현체를 접근할 수 있는 생성자, 정적 팩터리 메서드가 주로 사용되고 다른 방법으로는 프로퍼티 기반 방법도 가능하다.
모듈화 라이브러리의 "명세"는 인터페이스나 한두 개의 팩터리가 포함된 일부 패키지를 노출하는 모듈이며 해당 명세에서 허용되는 행위를 설명하는 문서도 동반한다.
"구현"은 단순히 명세 모듈에 의존하고 팩터리 구현체를 서비스 등록 시스템이 등록하는 노출된 패키지가 없는 모듈에 해당 됨.
"클라이언트"는 명세 모듈에 의존하고 팩터리 메서드를 호출하는 모듈에 해당되는

2. 상호컴포넌트 룩업과 통신

모듈화 설계의 유일한 목적은 애플리케이션의 개별 부분들을 다른 부분과 분리하는 데 있음.
두개의 모듈을 서로 독립적으로 만들고 싶다면 서로에 관해 알아서는 안되고 인터페이스를 이용해 상호작용해야 한다.

모듈 사용 시 환경 설정을 해야할 필요가 있는데 이 때 대부분의 프레임워크에서 하는 일은 의존성 주입(dependency injection)을 하며 주로 설정파일을 사용할 때가 많다.

- 의존성 주입

*** launcher 예제

모듈화 라이브러리에서는 적절한 초기화를 위해 registerXYZ를 수행하는 팩터리 클래스가 필요하다.
단 코딩 스타일의 미적 측면을 약화시킬 수 있고 절차적 등록으로 인해 (모듈갯수, 로드, 링크, 실행시간) 구동속도를 느리게 할 수 있다.

- 호출 이 필요없는(call-less) 연동 (프로퍼티기반)

*** system.getproperty 예제

연동코드를 실행할 필요가 없고 등록을 좀 더 선언적인 방식으로 수행
주로 System.getProperty()를 호출하는 방법임.
JDK에서 흔희 사용하는 괜찮은 방법이고 호출이 필요없는 등록을 허용하고 지연연동(late binding)도 가능하다.

app 개발자가 registerXYZ 호출 코드는 필요 없지만 일종의 설정을 제공해야 한다.
이는 앱 개발자에게 코드 작성 & 컴파일 & 실행 보다는 낫지만 그래도 클래스의 이름이나 시스템 동작에 대한 지식은 필요하다.
프로퍼티 기반 설정 중 널리 알려진 형식 중 하나는 스프링 프레임워크에서 제공하는 것으로 XML 설정 파일이다.

XML 설정 파일 예제

- 어노테이션 지정

스프링 2.5에서는 구현 클래스에 어노테이션을 지정하는 옵션을 제공함.

*** 어노테이션 예제

어노테이션으로 노출한 빈과 해당 빈의 이름, 다른 API에 대한 잠재적인 의존성까지 지정함.
app 개발자는 더 이상 모든 구현체 클래스의 이름을 참조하는 설정 파일을 작성할 필요가 없음.

*** 빈 설정 예제

이전 방식보다 알아야 할 지식의 양은 적어 졌지만 그럼에도 모든 구현체가 담긴 패키지의 이름은 알아야 함.

- Look Up

*** look up 예제

Lookup.getDefault()의 기본 구현은 JDK의 확장 메커니즘을 기반으로 하기 때문에 아무런 설정파일이 필요 없고 클래스패스만 올바르게 구성하면 된다.
org.apidesign.anagram.api.WordLibrary 와 같은 서비스를 찾을 경우

Lookup.getDefault().lookupAll(org.apidesign.anagram.api.WordLibrary.class) 를 실행하게 되고 이후
구현체에서는 현재 클래스패스를 발견하고 META-INF/services/org.apidesign.anagram.api.WordLibrary에 위치한 모든 리소스를 읽어 클래스명을 알아내기 위해 분석하고
클래스를 인스턴스화 한 후 해당 인스턴스들을 반환한다.

JDK6부터는 등록된 서비스 구현체의 전체목록을 조회하는 공개 API가 존재한다.

*** 예제

3. 확장점 작성하기

왓???

4. 순환 의존성의 필요성

순환 의존성은 레거시 코드를 다룰 때 꽤나 유용하다. 반면 이러한 기능을 새로 작성한 코드에 사용하는 것은 클래스와 모듈 간의 참조로 구성된 하나의 커다란 스파게티 접시를 만드는 것과 같다.

상호 참조는 Lookup을 사용하여 의존성을 제거할 수 있다.
또한 각각 독립적으로 실행되지 않으므로 필요로하는 의존성은 manifest에 명시를 하여 적절히 처리되도록 하는게 필요하다.

5. Lookup은 어디에나 있다.

JDK의 ServiceLoader와 달리 넷빈즈의 Lookup은 다수의 인스턴스를 가질 수 있고 각각은 개별 풀의 역할을 수행한다.
예를 들어 아이콘이 java.awt.Image로 변환되어야 할 필요성이 있는 경우 아이콘이 해당 class를 이미 가지고 있다면 loader에서 찾아 제공하고 아니면 이미지를 만들어 처리하면 된다.

*** 아이콘 예제

Lookup을 이벤트 버스 (event bus)로 생각할 수 있다. 객체가 들어오고 나오고 하는 곳 같이..

*** Modifiable 예제

다른 유용한 것으로는 질의 패턴(query pattern)이다. Lookup의 두가지 측면을 혼합한 것인데 적응형 패턴(adaptable pattern)에 대한 API가 될 수 있다는 것과 Lookup이 컴포넌트 주입에 대한 파사드가 될 수 있다는 것을 의미한다.

6. Lookup의 남용

Lookup의 동적인 특성은 대단히 흥미롭고 감동적이어서 불필요하게 사용할 때가 있다.
Lookup이 흥미로운 객체로 가득 찬 "마법 가방"의 역할을 하게 되는 것이고 API 사용자는 가방안에 손을 집어 넣어 아무것도 안 보이는 채로 특정 인터페이스를 찾는다.
인터페이스가 있다면 제대로 동작할 것이고 없다면 완전히 망가질 것이다.


------------------------------------------------------------------------------------
Chapter 8 : 클라이언트와 제공자를 위한 API를 분리하라.

클라이언트를 위한 API와 플러그인을 위한 서비스 제공자 인터페이스(SPI)는 다르다.

API 진화는 SPI 진화와 다르다.

클라이언트에게 메서드를 제공하는 API의 경우 추가와 관련된 문제는 없다.
새로운 메서드를 추가한다고 해서 바이너리 호환성이 깨지는 것은 아니고 클라이언트 입장에서는 더 많은 가능성과 선택권을 갖게 된다.

. SPI의 경우 정확히 그 반대다.
다른사람들이 반드시 제공해야만 하는 인터페이스에 새로운 메서드를 추가하면 사실상 기존의 모든 구현체가 망가진다.

. API를 적절히 나눠라.
API와 SPI를 분리하는 이유는 진화 문제 때문이었다.
다른 접근 법은 가독성이다.

모든 API(특히 자바로 작성된 API)는 지역성(locality)을 보이며 관련성 있는 것들은 서로 가까운 곳에 정의된다.
사용자에 관해 생각해 보고 사용자가 API에 기대할 만한 지역성을 사용자에게 제공하라.
- 관련 메서드는 같은 클래스에 배치한다.
- 관련이 없는 메서드를 어디에 둬야 할지 생각해낼 수 없다는 이유로 그것들이 이어써야 할 자리가 아닌 곳에 놓아서는 안 된다.
- 관련 클래스는 한 패키지 안에 넣어라.
- 특별한 상황에 유용한 추가적인 클래스는 다른 곳으로 옮긴다.

위 규칙들을 따르면 API의 지역성이 증가하고 결과적으로 API 내에서의 사용자 지향성이 대폭 증가할 것이다.

여러분이 만든 라이브러리의 인터페이스를 훨씬 더 많은 부분으로 나누는 것이 타당하다.
다음은 API를 네가지 서로 다른 범주로 정의한 넷빈즈 모듈의 예다.

- 핵심 API : 이 핵심 API를 사용하지 않고는 불가능한 일부 핵심적인 연산을 수행하고자 하는 평범한 관심사를 가진 사용자 그룹
- 지원 API : API 사용을 용이하게 하는 유틸리티 메서드 집합. 이러한 유틸리티 메서드는 반드시 사용해야 하는 것은 아니지만 API 사용자에게 편의성을 제공한다.
- 핵심 SPI : 라이브러리에 연결(plug in)하고자 하는 다양한 그룹의 사용자를 위한 인터페이스 집합.
- 지원 SPI : 이따금 연결할 인터페이스를 구현하는 것이 다소 복잡할 때가 있다. 다시금 도우미 인터페이스를 제공할 수 있다.

위는 넷빈즈의 특정 모듈에 어떤 것이 효과적인지만 보여주는 것이고
다만 넷빈즈 프로젝트를 진행하면서 저지른 실수로부터 얻은 교훈 중 하나는 바로 API가 사용의 지역성을 따른 다면 API 사용자의 삶이 향상된다는 것이다.

2017년 12월 11일 월요일

JAVA API 디자인, 5-6장

http://charlie0301.blogspot.kr/2017/12/java-api.html

책이 API 디자인 외에 한번쯤 library, framework을 고민한다면 읽어 볼 만함.
일부만 추려서 적었지만 책에는 더 좋은 내용이 자~알 설명 되어 있음.

------------------------------------------------------------------------------------
5장 : 필요 이상으로 노출하지 마라.

무언가를 API로 만들것이냐 만들지 말 것이냐를 결정하는데 유스케이스를 만들어 보라
특정 메서드나 클래스에 대한 유스 케이스가 없거나 미심쩍다면 API에 해당 요소를 빼는 편이 낫다.
API를 처음 릴리스하기 앞서 제거할 수 있는 것은 모조리 제거하라는 것이다.


1. 필드를 감춰라, 직접 노출하기 보다는 필드에 접근하는 메서드(getter, setter)를 사용하는 편이 낫다.
읽기, 쓰기만 가능한 필드 보다 추가작업을 할 수 있다.

2. 생성자보다 팩터리가 낫다.
생성자 대신 팩터리 메서드를 노출할 경우 나중에 API를 진화시키기 수월해진다.

 1. 팩터리의 반환 클래스 타입을 유연(다형성)하게 제공할 수 있다.
 2. 인스턴스를 캐싱할 수 있다.
 3. 동기화가 가능하다.

3. 모든 것을 final로 만들어라
서브 클래싱을 허용하는데는 생각치 못한 결과가 발생할 수 있으므로 class를 final로 만들어라.

4. 어울리지 않는 곳에 설정자 메서드를 넣지 마라.
설정자(setXXXX)는 구현 세부사항을 API 사용자가 아는 상황에서 사용 가능하다.
API의 기능을 풍부하게 만들기 위한 방법으로 주로 사용되는데 역효과(유지보수, API 시맨틱 파악 어려움)가 발생한다.

5. 프랜드 코드에서만 접근하는 것을 허용하라.
API에서 너무 많은 것들을 호출하지 않으려고 할 때 또 한가지 유용한 기법은 특정 기능에 대한 접근 권한을 "프랜드(friend)" 코드에만 부여하는 것이다.

- "Only for internal use", "Do not call me" 이딴 설명을 API에 적지 말고 접근권한 변경으로 사용자에게서 숨겨라.

6. 객체를 만든 이에게 더 많은 권한을 부여하라.
(TBD)

7. 깊은 계층구조를 노출하지 마라.
(TBD)


------------------------------------------------------------------------------------
6장 : 구현이 아닌 인터페이스를 대상으로 코드를 작성하라.

1. 메서드나 필드 제거하기

일단 공개된 인터페이스나 클래스에서 메서드나 필드를 제거하는 것은
기존 API 사용 코드들에서 컴파일 에러를 발생 시키고 나아가서 바이너리 호환성도 보장하지 않는다.

private, package private, protected abstract(설계 실수)는 제거 가능
public, protected(설계 실수) 는 제거 불가


2. 클래스나 인터페이스를 제거하거나 추가하기

제거는 소스및 바이너리 차원에서 문제를 일으킴, 공개된 것들은 계속 유지하는 것을 권고
추가는 문제 없음. 다만 와일드카드 임포트를 이용할 경우 소스 호환성이 깨질 수 있음.


3. 기존 계층 구조에 인터페이스나 클래스 집어 넣기

가능, 제약 조건은 원본 및 새로운 타입에서 접근할 수 있었던 메서드 전체가 동일하게 유지되거나 최소한 줄어들지 않아야함.


4. 메서드나 필드 추가하기

필드의 경우 앞서 말한 것과 같이 바이너리 호환성을 지원할 수 있는 static final이 아닌 이상 API에 추가해서는 안된다.

정적 메서드를 추가하는 것은 바이너리 관점에서 수용할만하지만 클래스에서만 사용해야 한다.
정적 메서드와 중복 정의된 비슷한 메서드의 변종들로 비호환성을 야기하거나 컴파일 오류를 만들 수 있다.

서브클래싱이 가능한 클래스에 추상 메서드를 추가하는 것은 호환성을 깨뜨리는 변경사항에 해당됨. 이는 인터페이스를 사용하는 구현에서 런타임 예외를 발생 시킬 수 있다.
즉 추상메서드를 서브클래싱이 가능한 클래스와 인터페이스에 추가하는 것을 최소화 해야 하던가 클래스와 인터페이스를 서브클래싱 할 수 없게끔 만들어야 한다.

5. 자바 인터페이스와 클래스 비교

자바 인터페이스의 가장 큰 기능은 다중 상속이지만 실제로 성능, 점유 메모리의 양을 최소화 하기 위함이다.
다중 상속이면 하나의 객체로 API 인터페이스를 무제한 상속 가능하지만 클래스의 경우 API 클래스 마다 하나의 하위 클래스를 생성해야 하고 다른 클래스와 연관된 경우 위임을 통해서 인스턴시를 연결해야 한다.
단 한 두개 보다 상당한 객체들을 생성하는 경우에만 상당한 효과가 있다.


6. 외유내강

인터페이스 관점에서 기존 인터페이스에 메서드를 추가하는 것이 다소 어렵다.
하지만 이를 인터페이스의 강점으로 대처할 수 있는데
각기 버전마다 인터페이스를 만들어 제공하는 것이 방법이 될 수 있다.
Language13, Language14, Lauguage15 와 같이 인터페이스르 만들어 제공하면 사용자는 필요한 것을 선택해 사용함.
단 너무 인터페이스가 급격히 늘어나면 클라이언트 코드가 복잡해 질 수 있다.


7. 메서드를 추가하길 좋아하는 사람들의 천국

메서드가 완전히 바이너리 호환성을 보장하도록 하게 위해서는 final 클래스 형태로 표현한다.
이는 서브클래싱도 막을 수 있고 인터페이스나 추상 클래스에 메서드가 추가됐을 때도 문제는 없지만
추가된 메서드를 호출되는 경우에는 문제가 된다
클래스 파일에서 메서드의 이름과 매개변수, 반환형을 기준으로 호출된 메서드를 완전히 구분하므로
이름과 인자수가 같은 메서드를 추가하지 않아야 문제를 방지할 수 있다.

8. 추상 클래스는 유용한다.
지금까지 불변적인 계약을 정의하고 싶을 때 자바 인터페이스를 사용하고
메서드를 추가할 능력을 갖추고 싶을 때 자바 final 클래스를 사용해야 한다고 주장
반면에 추상 클래스를 사용할 이유는 실제로 없다.

자바 인터페이스와 비교 시 자바 추상 클래스의 한가지 이점은 정적 메서드를 포함할 수 있어 추상 클래스에 정적 팩터리 메서드를 만들 필요성이 있다면 사용 가능하다.

자바 인터페이스에 비해 자바 클래스의 유용한 특징은 접근 권한을 제한할 수 있다.
추상클래스를 만들어 제공할 경우 구현할 수 있는 클래스 제한은 런타임 시 클래스 타입을 보고 제한할 수 있다.

9. 매개변수 증가를 위한 대비
response/reply 패턴?

10. 인터페이스 대 클래스
구현이 아닌 인터페이스(자바 인터페이스가 아니라 추상적인 정의)를 대상으로 코드를 작성하라.
자바 인터페이스를 사용해서 불변적인 타입을 명시하고 메서드를 안전하게 추가할 수 있는 곳에서는 final 클래스를 타입으로 사용한다.
목표가 완전한 바이너리 호환성을 보장하는 것이라면 다른 누군가가 구현할 수 있는 클래스나 인터페이스에 절대 메서드를 추가해서는 안된다.

2017년 12월 4일 월요일

Java API 디자인 책, ~4장

필요에 의해 이 책을 보게 되었는데..

책에 써 있는대로 3일만에 뚝딱 읽을 수 있는 책이 아님.
너무 말이 많다. 하지만 내용은 좋아서 두고 보고 싶지만 대출기간이 짧아서 좀..

http://www.yes24.com/24/goods/17713587?scode=032

독자분들께,
서점에서 이 책을 손에 들고 “이 책을 사야 할까?”라고 자문하고 계신다면 저는 이렇게 답하겠습니다. 만약 여러분이 작성한 코드가 다른 사람들이 작성한 코드를 컴파일하는 데 필요하다면 여러분은 API의 세계에 들어갈 준비가 된 것입니다. 그리고 이 책은 여러분이 API의 세계를 탐험하도록 도와줄 것입니다.
하지만 이 책은 “5번의 손쉬운 강의로 API 설계를 가르쳐 드리지” 않습니다. 이 책은 “단 3일만에” 읽을 수 있는 책이 아닙니다! 빠르게 읽을 수 있는 지침서를 찾고 계신다면 아마 이 책은 아닐 것입니다. 한편으로 API 설계에 관한 깊이 있는 지식, 즉 API 설계에 대한 “어떻게”뿐만 아니라 “왜”에도 관심이 있다면 이 책을 책장에 다시 내려놓으시기 전에 저를 잠깐 소개해 드리겠습니다.

일단 읽은 부분 까지만 간략히 정리를 하려고 했는데
도저히 1-3장은 요약을 못하겠음. 대신 목차만 보자면..


[1부] 이론과 정당성

애플리케이션 프로그래밍 인터페이스(API; Application Programming Interface)를 만들고 설계하고 작성하는 과정은
예술적인 탐구이자 과학적인 탐구로 볼 수 있음.
관점에 따라 API 아키텍트는 세상을 바꾸려는 예술가이거나 여러 세계를 잇는 다리를 만들려는 기술자에 해당한다.

나머지는 요약 불가...

1장: 현대 소프트웨어 구축의 예술
  합리주의, 경험주의, 무지
  지금까지의 소프트웨어의 진화
  거대한 기반 요소
  아름다움, 진리, 우아함
  더 무지해져라!

2장: API를 만드는 이유
  분산 개발
  애플리케이션 모듈화
  비선형적인 버전 관리
  중요한 것은 의사소통이다
  경험적 프로그래밍
  첫 번째 버전은 늘 쉽다

3장: 훌륭한 API를 결정하는 요소
  메서드와 필드 시그너처
  파일과 파일의 내용
  환경변수와 명령줄 옵션
  API로서의 텍스트 메시지
  프로토콜
  동작 방식
  I18N 지원과 L10N 메시지
  넓은 의미의 API
  API의 품질을 검사하는 법


4장: 시시각각 변하는 표적


1. 첫 번째 버전은 결코 완벽하지 않다.
 API 개선 시 API 사용자에게 문제를 일으키지 않도록 설계해야 한다.

2. 하위 호환성

. 소스 호환성
 = API가 변경되어도 컴파일 될 수 있는가?

클래스에 새 메서드를 추가하는 것도 소스 호환성을 깰 수 있다.
필요 없는 class들을 import하는 wildcard import 로 호환성이 깨질 수 있다.

. 바이너리 호환성
 = 이전 버전의 라이브러리를 가지고 컴파일된 프로그램이 다시 컴파일하지 않고도 새로운 버전의 API와 링크 될 수 있는가?
이로 인해
1. 애플리케이션을 작성한 다음 그것을 한 버전의 라이브러리와 컴파일하는 동시에 사람들이 다른 버전으로도 사용하게 만들 수 있고
   애플리케이션의 유지보수와 패키징, 배포가 대폭 간소화 된다.
2. 이전 버전의 라이브러리를 대상으로 빌드 된 바이너리만 가지고 있는 사용자가 애플리케이션이 재 컴파일될 때까지 기다리지 않고도
    새로운 버전의 라이브러리로 마이그레이션 할 수 있다.

가상머신이 메서드를 찾을 때는 모든 가능한 상위 클래스까지 찾는데 비해 필드를 찾을 때는 지정된 클래스에서만 필드를 찾는다.
결과적으로 필드대신 메서드를 노출하는 편이 추후를 위해서 낫다.

객체 지향 언어에서 메서드를 선언한는 것과 재정의하는 것과 관련해서 가상 메서드 테이블(virtual methods table)를 알아야 한다.
final 키워드를 지정하지 않은 메서드가 여러개 포함된 클래스를 정의할 경우 사실상 테이블을 하나 만들게 된다.
이 테이블에는 메서드의 이름들(프로토타입 포함)이 해당 메세드를 호출 했을 때 실제로 실행되는 코드와 매핑되어 있다.
하위 클래스를 만들면 앞에서 말한 테이블이 만들어지고 이 테이블은 특정 메서드가 호출됐을 때 실행되는 새로운 코드를 가리키는 다른 포인터들로 채워진다.
이후 메서드를 호출하는 코드에서는 항상 테이블을 검사해서 시그너처를 기준으로 올바를 메서드를 찾아 테이블에 등록된 실제코드를 호출한다.

API 클래스에 public static final 문자열이나 정수 상수를 정의한다면 평범한 object나 다른 타입의 경우처럼 참조되지 않고 대신 그것을 참조하는 클래스로 복사된다. 이는 새 버전의 API에서 원시 상수 같은 것들의 값을 변경하더라도 해당 API의 클라이언트(이미 사용중인)가 보는 값은 변경되지 않는 다는 것을 의미한다.

. 기능적 호환성
 = 어떤 App을 새 버전의 라이브러리를 대상으로 실행했을 때와 이전 버전의 라이브러리를 대상으로 실행했을 때 동일한 결과를 보이는가?
이를 위해서는 API가 어떤 일을 해야 할지 명확하게 이해하고 그것을 실제 프로그래밍 언어로 표현하는 기술이 탁월해야 하며, API 사용자가 API를 어떻게 사용할 지 예상할 수 있어야 한다.

. 유스 케이스 지향의 중요성
API를 통해 무슨일을 할 수 있고 왜 해야 하고 어떻게 할 수 있는지를 파악하기 위해 API 사용자에 대해 생각해볼 필요가 있다.

유스 케이스는 인공적인 것에 불과하고 현실과 거리가 멀 수도 있고 API 실제 사용자의 요구사항과 다를 수 있다.

유스 케이스는 API에서 의도하는 사용법을 설명한 것으로 잠재 사용자가 겪을 수 있는 문제를 구체적인 해결책 없이 보여준다.
잠재적인 문제를 사람들이 겪을 가능성이 높은 실제 문제와 최대한 가깝게 만드는 것은 진짜 유용한 해결책(API)을 만들어 내기 위한 훌륭한 첫걸음이다.

시나리오는 추상적인 유스 케이스를 API에서 실제로 실현된 내용과 연결된다. 시나리오에서는 어떤 클래스나 인터페이스를 구현해야 하고.
그것들을 등록하려면 선언적인 파일을 어디에 어떻게 넣어야 할지 기술한다.

. API 검토
API 변경 요청을 제출 시 다음의 "성공적인 API 설계를 위한 규칙"을 충족하는 지 검사한다.
-  유스 케이스 기반 API 설계
 : API 설계 동기가 추상적이고 일반적인 수준으로 기술돼 있으며, 이를 통해 실제 시나리오에 대한 일반적인 설계 결정과 API가 최종적으로 실현된(javadoc) 결과물이 연결된다.
- 일관성 있는 API 설계
 : 개별 개발자가 만든 API는 반드시 팀 전체에서 공유하는 일반적인 "모범 사례"와 부합해야 한다.
- 단순하고 깔끔한 API 설계
 : 간단하고 공통적인 작업은 쉬워야 한다. 중요 유스케이스가 구현하기 쉬운 시나리오를 통해 충족되는지 확인할 수 있다.
- 더 적은 것이 더 많다.
 : 유스 케이스에 기술된 대로 딱 필요한 기능만 노출돼야 한다. 이렇게 하면 API 사용 범위의 예상과 현실간 차이를 방지할 수 있다.
- 진화 대비
 : 라이브러리는 반드시 나중에 유지 보수할 수 있어야 한다. 새로운 요구사항이 나타나거나 기존에 유지 보수하던 사람이 떠나더라도 API가 위태로워져서는 안 된다.

. API 생명주기
넷빈즈의 API 범주
- 비공개(Private) : 접근 가능하나 모듈과 라이브러리 외부에서 사용할 용도로 만들어진 것은 아닌 기능에 부여하는 범주
- 프렌드(Friend) : API는 시스템의 다른 부분(한정된 영역)에서 사용하기 위해 고안 된 범주
- 개발 중(Under development) : 안정적인 API 될 것으로 예상되는 불완전한 계약
- 안정(Stable) : 제품 품질에 도달했고 공개적으로 사용할 준비가 된 인터페이스에 사용됨.
- 공식(Official) : API는 안정적이면서 제품에 패키징 된 상태
- 서드파티(Third-party) : 인터페이스는 내부 규칙을 따르지 않는 측에서 제공된 범주, 이러한 인터페이스를 노출해서는 안된다.
- 표준(Standard) : 서드파티 분류와 비슷하다.
- 지원중단(Deprecated) : 어느정도 시간이 흐른 후 거의 모든 API는 현재 상태와 상관없이 쓸모가 없어지거나 새로운 API로 대체된 경우 해당되는 범주

. 점진적 향상
점진적 변경 vs 빅뱅 방식
점진적 변경 : 라이브러리 기능은 보전하면서 새로운 메서드나 클래스를 추가하거나 새로운 엘리먼트를 추가하는 것
빅뱅 방식 : 보통 기존 API를 완전히 개조해서 새로운 버전을 만들어내는 행위

"사소"한 점진적 변경이라도 API 사용에 심각한 악영향을 줄 수 있다.
빅뱅은 하위 호환성에 대해 현실적이지만 사용자들이 새로운 API를 사용하고 적응하는데 시간과 비용이 필요하고 사용자들은 뭔가 새로운 장점이 있을 것이라고 기대할 수 있다.

결론적으로는 빅뱅방식에 비해 피해가 적은 점진적 변경을 준비해야 한다. 하지만 API가 형편 없어 점진적 변경이 불가하다면 빅뱅방식의 변경이 정당화 될 수 는 있다. 단 API 사용자들의 고통을 수반한다는 것을 염두해야 한다.


나머지는 나중에..