ADR을 써야 하는 이유
(github.blog)ADR = Architecture Decision Records
아키텍처적인 결정을 왜 그렇게 내렸는지 코드 베이스안에 기록해 놓는 것.
GitHub은 iOS/Android 모바일팀에서 이걸 적용하고 있으며, 왜 필요한지를 설명한 글
당신을 위한게 아니라, 미래의 당신을 위한 것
ADR은 내가 내린 결정에 대한 반성과정이 아니고, 지금부터 6~12개월후에 이 아키텍처를 결정했을때의 마인드셋을 기억하는데 도움이 됨.
ADR은 결정이 내려지는 시점을 포착하여 회의/줌 미팅/Slack/코드에서 다뤄진 PoC 까지를 모두 포함.
머리에 있는 이 컨텍스트를 말로 끄집어 내서 나중에 이 아키텍처를 다시 살펴볼 때 해당 컨텍스트를 다시 머리에 넣을수 있게 하는 것.
진짜 보너스는 누군가 몇달후에 왜 GitHubAPIClient 모듈이 이렇게 동작하는지 당신을 비난하면서 물어볼 때 나타남.
30분 페어링해서 코드를 설명하는 것 보다, 이 ADR을 던져주고 그 모듈을 빌드하는 동안 내린 결정에 대해 설명할 수 있게 됨.
당신을 위한게 아니라, 당신의 동료를 위한 것
ADR은 한줄짜리 "이 기능은 피쳐-#3128의 구현입니다" 라는 설명보다 더 긴 내용을 적을 것.
동료들이 왜 이 기능이 다른 방식이 아닌 이 방식으로 만들었는 지를 이해하는데 도움이 되는 좀 더 긴 설명 형식.
(ADR 내에 "고려했던 대안들" , "장점과 단점" 등으로 표현 )
당신에게는 간단한 것도, 동료들에게는 복잡할 수 있음.
시간을 좀 내서, 결정을 내릴 때 생각한 과정을 적어두면 팀원들이 당신의 머리 속에 들어올 기회를 주게 됨.
ADR을 작성하면 "Decision Socialization(의사 결정의 사회화)"가 가능해짐.
이렇게 하면, 개별적으로 결정을 내리는 대신 팀이 유지 관리에 대한 책임을 지는 결정을 내리게 함.
풀 리퀘스트를 올리기전에 ADR을 작성하면 이를 검토하는 팀으로 부터 더 좋은 PR리뷰를 받을수 있음.
당신을 위한게 아니라, 미래의 동료를 위한 것
ADR은 당신이 얼마나 똑똑한 지 보여 주거나, 사람들이 당신이 만든 아키텍쳐를 보고 어리둥절하게 하는 것이 아님.
ADR은 새로운 팀원이 들어왔을 때 그들이 현재의 코드베이스와 코드베이스가 지난 시간동안 어떻게 발전해왔는 지를 이해하는데 도움이 됨.
팀이 확장되고 성장하면서 팀원간의 커뮤니케이션 경로는 늘어남.
이렇게 내린 결정을 적어두면 팀이 성장하면서 새로 합류하는 사람들과도 의사소통 하는데 도움이 됨.
최상의 시나리오는, 당신의 팀원이 새 ADR을 작성해서 당신이 예전에 내렸던 결정을 대체하고, 미래엔 당신의 동료로부터 배울 수 있게 되는 것.
"더 많은 ADR을 작성하세요. 우리 팀이 커지고 코드베이스가 복잡해질 때마다 ADR은 미래의 우리와 현재 팀원과 미래의 팀원을 도울 수 있는 좋은 방법 입니다."
전자정부 사례중에 유명한 Gov.UK 가 자신들의 AWS 클라우드 아키텍쳐 관련 ADR을 정리한 Repository 도 있습니다.
https://github.com/alphagov/govuk-aws/…
ADR 사례들
CSS 프레임워크 결정
https://github.com/joelparkerhenderson/architecture_decision_record/…
- 이슈 : 웹앱을 위한 CSS프레임워크 결정이 필요. 유명 브라우저 및 화면 사이즈 상관없이 빠르고 안정적이어야 함. 디자인/레이아웃/UI/UX 에서 빠른 이터레이션. 반응형 디자인
* 결정 : Bulma 를 사용하기로 결정
- 전제 : 모던하고 빠르고 반응형인 웹앱을 만들고 싶으니, jQuery는 안쓰고 싶음
- 제약 : jQuery는 쓰지 않아도 되는 프레임워크
- 고려 : 아무것도 안쓰거나, Bootstrap/Bulma/Foundation/Materialize/Semantic UI 중에서 Bulma 와 Semantic UI를 깊게 고민
Monorepo vs Multirepo
https://github.com/joelparkerhenderson/architecture_decision_record/…
- 이슈 : 우리 프로젝트는 세개의 메인 카테고리 - 프론트엔드 UI,미들웨어,백엔드 서버
ㅤ→ SCM으로 git을 사용중인데, monorepo vs polyrepo vs hybrid 를 결정해야함
* 결정 :
ㅤ→ 조직/팀/프로젝트가 작고 빠른 이터레이션일 때는 Monorepo
ㅤ→ 조직/팀/프로젝트가 크고 안정적인게 중요할때는 Polyrepo
- 전제 : 우리가 만드는 코드는 조직을 위한것이고 외부(공공)을 위한것이 아님
프로그래밍 언어 결정
https://github.com/joelparkerhenderson/architecture_decision_record/…
- 이슈 : 소프트웨어 개발용 언어를 결정해야함. 웹 프론트와 백엔드
* 결정 :
ㅤ→ 프론트엔드는 TypeScript
ㅤ→ 백엔드는 Rust
- 전제 :
ㅤ→ 프론트는 일반적이지만 빠르게 개발,배포,반복이 되어야함. 레거시 호환 필요없음
ㅤ→ 백엔드는 일반적인것보다는 약간 높음. 품질,안정성,보안에 대한 고려. 거의 실시간 수준이 필요(GC에 의해서 멈추는것은 없어야함). 함수형 프로그래밍 / 병렬처리 및 멀티코어 프로세싱, 메모리 안전성도 중요함
- 제한 : 메이저 클라우드서비스의 서버리스(Amazon Lamba)에서 꼭 실행가능 해야함
- 고려 : C/C++/Clojure/Elixir/Erlang/Elm/Flow/Go/Haskell/Java/Javascript/Kotlin/Python/Ruby/Rust/TypeScript
- 논쟁 :
ㅤ→ C : 낮은 안전성으로 제외; Rust가 대부분의 것들을 더 잘할 수 있음
ㅤ→ C++ : 난잡(mess)해서 제외; Rust가 대부분의 것들을 더 잘할 수 있음
ㅤ→ Clojure : 뛰어난 모델링; Lisp 과 가장 비슷; JVM상의 훌륭한 런타임
ㅤ→ Elixir : 배포 및 동시성이 뛰어난 런타임; 훌륭한 개발자 경험; 상대적으로 작은 에코시스템
ㅤ→ Erlang : 배포 및 동시성이 뛰어난 런타임; 다소 도전적인 개발자 경험; 상대적으로 작은 에코시스템
ㅤ→ Elm : 전도유망; IBM이 좋은 사례들을 공유중; 작은 에코시스템
ㅤ→ Flow : JS의 흥미로운 개선; 하지만 개발자들이 멀어지는 중
ㅤ→ Go : 뛰어난 개발자 경험; 뛰어난 동시성; 언어를 이상하게 만드는 나쁜결정들이 있었음
ㅤ→ Haskell : 최고의 함수형 언어; 작은 개발자 커뮤니티; 프로덕션 성공 사례가 많지 않음
ㅤ→ Java : 최고의 런타임; 뛰어난 에코시스템; 그저그런 개발자 경험
ㅤ→ JavaScript : 가장 인기있는 언어; 가장 넓은 에코시스템
ㅤ→ Kotlin : Java의 많은 것을 개선; JetBrains의 훌륭한 후원; Java to Kotlin 한 다양한 성공사례
ㅤ→ Python : 시스템 관리쪽에서 가장 인기있는 언어; 좋은 분석 도구; 좋은 웹 프레임워크; Google이 Go를 선택하면서 버려짐
ㅤ→ Ruby : 최고의 개발자 경험; 최고의 웹 프레임워크; 훌륭한 커뮤니티; 엄청 느림; 패키징 하기 어려움
ㅤ→ Rust : 최고의 새 언어;Zero-cost abstractions(추상화해도 속도가 느려지지 않음) 강조; 동시성 강조; 상대적으로 작은 에코시스템; 몇몇 컴파일러 최적화에서는 한계가 있음 (메모리 직접접근은 unsafe여야 하는등)
ㅤ→ TypeScript: JavaScript에 Type을 추가; 뛰어난 Transpiler; 개발자들이 점점 JS 에서 TS로 넘어가는 중; Microsoft 의 강력한 후원
- VM기반은 선택하지 않기로함 (복잡성이 증가하기 때문에)
- 가장 빠른 런타임을 위해서는 JS 와 C를 선택
- 최고와 거의 비슷하게 빠른 런타임을 위해서는 TypeScript 와 Rust를 선택
- 만약 VM과 웹프레임워크 선택했다면
ㅤ→ Closer 와 Luminous
ㅤ→ Java 와 Spring
ㅤ→ Elixir 와 Phoenix