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 사용자들의 고통을 수반한다는 것을 염두해야 한다.


나머지는 나중에..




댓글 없음:

댓글 쓰기