-
외부 라이브러리나 프레임워크 등 의존성 도입에 따른 비용과 리스크를 경계하는 관점임
- 의존성은 학습 부담, 인터페이스 변경에 따른 코드 수정 등 여러 숨은 비용이 있음
-
Tigerbeetle와 같이 제로 의존성 전략을 채택한 사례가 장기적으로 보안과 유지보수에 이점이 있음
- 좋은 의존성의 기준으로 보편성, 안정성, 깊이, 사용성, 완결성 등 다섯 가지 평가 프레임워크를 제시함
- 의존성 선택 시 단기 생산성만이 아니라 전체 비용과 위험을 감안한 신중한 판단이 필수임
NIH(Not Invented Here)보다 잘못된 의존성이 더 큰 비용임
의존성의 단점과 숨겨진 비용
- 개발에서 외부 의존성 사용이 마치 공짜처럼 여겨지는 현상에 대한 지적임
- 실제로는 의존성 도입이 학습 비용, 복잡한 설치 및 배포 과정, API 변경 시 대규모 코드 수정 등 여러 비생산적인 리스크를 동반함
- 대규모 서드파티 의존성의 학습 및 설치보다 직접 기능을 구현하는 것이 빠른 상황도 빈번함
- 배포, 컨테이너화, 번들링 등의 복잡성이 의존성 도입만으로 발생하는 경우가 많음
- 주기적 릴리즈, 메타의 변화, 클라이언트 환경 불일치 등도 문제로 작용함
Tigerbeetle의 접근법: 제로 의존성
-
Tigerbeetle은 Vanilla Zig 기반의 재무 데이터베이스로, 제로 의존성 정책을 채택함
- Zig 툴체인 외의 외부 의존성을 두지 않음
- 의존성으로 인한 공급망 공격 위험, 성능 저하, 설치 시간 증가 등 문제를 피하려는 목적임
- 인프라에 깊게 뿌리내린 소프트웨어일수록 의존성으로 인한 비용이 전체 스택에 증폭됨
- 표준화된 작은 툴박스 활용이 유지보수와 개발 능률에 유리함
-
Zig 하나로 새로운 문제를 빠르게 다루고 복잡도를 줄이는 데 집중함
의존성 평가 프레임워크
-
모든 개발자가 완전한 무의존은 불가능함을 인정하면서도, 의존성은 신중히 평가해야 함을 강조함
-
다음의 다섯 가지 기준을 통해 의존성을 평가해야 함
-
보편성(Ubiquity) : 대상 환경에 사전 설치되어 있을 확률, 별도 번들 필요성 여부
-
안정성(Stability) : 호환성 깨짐, API 변경 빈도, 지원 중단 등 이슈 발생 빈도
-
깊이(Depth) : 의존성이 제공하는 기능의 레이어 수준과 대체 구현의 난이도
-
사용성(Ergonomics) : API가 직관적/선언적이며 쓰기 쉬운지, 문서화 현황
-
완결성(Watertightness) : 추상화가 잘 이루어져 하위 레이어를 신경 쓸 일이 적은지
-
개발 커뮤니티는 주로 사용성만 논의하며 나머지 네 가지는 간과되는 경우가 많음
좋은 의존성의 사례
POSIX 시스템 호출
-
보편성: Linux, Android, macOS, BSD 등 거의 모든 플랫폼에서 사용 가능함
-
안정성: 인터페이스 호환성이 매우 높고 변화 거의 없음
-
깊이: 단일 API로 수십만 줄의 커널 코드 감춤
-
사용성: 다소 전통적인 C 스타일이기는 하나 사용에 큰 무리는 없음
-
완결성: 대부분 문제 없으나 저장 장치의 데이터 영속 처리 등 세부 이슈 있음
ECMA-48 터미널 제어 코드
-
보편성: Windows의 cmd.exe를 제외하면 대부분의 터미널에서 지원함
-
안정성: 1991년 이후 변경 없음
-
깊이: 직접 표준을 만드는 것이 터무니없이 힘듦
-
사용성: Esc 캐릭터로 인한 난독성을 제외하면 무난함
-
완결성: 하드웨어 의존성 걱정이 매우 적음
웹 플랫폼 (Web API, HTML, JS, CSS 등)
-
보편성: 웹 브라우저가 전 세계 거의 모든 환경에 설치됨
-
안정성: 강력한 하위 호환성 정책
-
깊이: 자체 브라우저 제작은 현실적으로 불가능할 정도로 깊음
-
사용성: 약간의 복잡함 있으나 문서화와 개발 도구 우수함
-
완결성: 파일, 오디오, 비디오 등 특이 상황 제외하면 매우 완결성이 높음
결론과 제언
- 나쁜 의존성의 구체적 예시는 독자의 숙제로 남김
-
카피-앤-페이스트, 의존성 남용 대신 비판적 사고와 총체적 비용 분석이 필수임
- 의존성을 도입할 때는 이득뿐만 아니라 전체 시스템의 잠재적 위험과 비용도 반드시 고려해야 함