문서 작성은 영원히 논란이되는 주제입니다. 내 경험에 따르면, 소프트웨어 엔지니어링은 소스 코드나 기능 출시와 같은 유물의 비즈니스 가치에 너무 집중하여 다른 것들에 대해 덜 중요하게 여깁니다. 항상 사람들이 말할 때 '애자일 방법론에서 요구되는 문서만 작성해야 한다'거나 '디자인 문서를 작성하는 것은 시간 낭비다'라고 말하는 것을 듣습니다. 이런 주장에는 일부 진실이 있으며, 보통 개발 중인 문서가 대상 그룹에게 지속적인 가치를 제공하지 못하기 때문입니다.
누군가 다른 사람이 작성한 나쁜 문서에 대해 불평하는 소프트웨어 엔지니어를 들을 때, 왜 우리가 전혀 문서를 작성해야 하는지 고민합니다. 그러나 때로는 매우 잘 쓰여진 문서를 발견하여 그 가치를 깨닫게 됩니다. 안타깝게도, 많은 사람들에게는 명백한 점이지만 일부 사람들에게는 명확하지 않을 수 있는데, 문서 작성은 과학보다는 예술에 가깝고, 대부분의 소프트웨어 엔지니어들은 예술가가 아닙니다.
사실 효과적인 문서 작성에는 많은 기술이 필요하기 때문에, 컴퓨터에 무언가를 시키는 논리와 정확성에 훈련받은 사람에게는 타고난 능력이 아닙니다. 개인적으로 나는 쓰기를 배우거나 뛰어나려고 노력하지 않았다면 '코드를 읽어라'하고 코드가 하는 일을 이해하기 위해 주석이나 다른 형태의 문서를 신경 쓰지 않고 끝낸 사람으로 쉽게 상상할 수 있습니다. 그러나 내 20년 가량의 소프트웨어 엔지니어 경력 중에, 어떤 것이 특정 방식으로 구현된 이유를 설명하는 잘 위치한 주석이나 다른 접근법이 거부되었을 때의 트레이드 오프를 설명하는 문서가 나에게 시간과 노력을 아낄 수 있었고 코드베이스의 변화를 쉽게 파악하고 수정할 수 있게 해주었습니다.
그리고 여기, 친구들, 그 가치가 있습니다.
좋은 문서는 대상 독자를 염두에 두고 이해를 촉진하는 관점을 제공합니다.
소개
이야기 시간!
저는 Friendster에 있을 때 프로덕션에서 지속적으로 발생하는 다양한 도전에 직면하게 된 소프트웨어 엔지니어링 그룹에 참여했어요. 그곳은 키인 지식재산을 바탕으로 기능을 제공하면서 빠른 환경에서 계속해서 발전하고 있었답니다. 당시에 Friendster는 사용자들 간의 연결을 유지하는 핵심 기술인 Graph Server에 특허를 보유하고 있었죠.
여기서 고려된 아이디어는 인접 목록을 유지하고 Memcache 서버 pool에 분산시키는 것이었어요. N개의 Memcache 서버로 이뤄진 링과 풀 크기가 3인 풀을 구성할 수 있도록 풀을 설정할 수 있었죠. 데이터의 사본이 있는 3개의 논리적으로 이웃하는 서버로 이뤄진 풀이 생겼어요. 이렇게 하면 Memcache 서버 중 하나가 다운되어도 데이터의 사본이 유지되는 백업이 가능했지만, 클라이언트는 읽기 경로에서 3개 중 1개를 선택해 데이터를 요청하고 쓰기 경로에서는 3개 모두에 데이터를 쓸 수 있었죠. 이 설계에는 더 많은 장점이 있었지만, 그것은 이 기사의 주제가 아니에요. :)
저는 Graph Server를 개선하여 그 내구성, 효율성, 성능, 확장성을 향상시키는 작업을 맡았었어요. 우리는 2007-2008년에 사용할 수 있었던 도구를 활용하여 그 목표를 대부분 성공적으로 이루어냈어요.
단점 중 하나는 그 당시에 출발점으로 사용할 좋은 문서가 없었다는 것이었죠.
그래프 서버는 HTTP 1.0/1.1 요청을 처리하는 C++ 서비스로 구현되었습니다. HTTP URI는 특정 작업을 나타냈습니다. 이것은 정확히 REST API가 아니었고, 이것은 리소스 기반 API 설계가 인기를 끌기 전의 것이었습니다. 구현에는 충분한 주석이나 구현 방식에 대한 문서화된 설계 결정이 부족했습니다.
Part 1에서 이를 어느 정도 설명했고, Part 2에서는 처음부터 교체를 위한 프로젝트를 시작하는 방법을 설명했습니다. 여기서, 저는 서로 다른 종류의 문서화로 문서화 결핍을 점진적으로 채우는 방법을 설명하려고 합니다.
문서 종류
문서화에는 많은 종류가 있습니다. 실제로, 지금 읽고 계신 것도 문서화의 한 종류입니다. (어떤 사람들은 이것을 지식 베이스 문서라고 부를지 몰라도 나중에 지식 베이스와 그 구축 방법에 대해 이야기하겠습니다.) 이 기사에서는 일반적인 소프트웨어 엔지니어링 프로젝트에 관련된 몇 가지 문서 유형을 다루겠습니다. 이것들은:
- 인라인/코드 문서화: 이러한 문서들은 일반적으로 프로그램 소스 코드 내에서 주변 코드의 특정 측면을 설명하는 주석으로 호스팅됩니다. 때로는 이러한 주석들이 파싱되어 추출되어 HTML이나 PDF 파일과 같은 외부 자료로 볼 수 있도록 자동화된 도구를 사용하여 프로그램 구조와 함께 제공됩니다.
- 시스템 문서: 이러한 문서들은 일반적으로 시스템(다이어그램이 포함되어 있거나 포함되어 있지 않은)과 상호 작용하는 구성 요소를 묘사하는 독립적인 문서입니다. 일부 장소에서 시스템 설계 문서, 기술 설계 문서 또는 소프트웨어 설계 문서로 불립니다. 미리 정의된 템플릿을 따르거나 시스템 수준의 속성을 최소한 다룹니다.
- 사용자 매뉴얼: 사용자가 시스템과 상호 작용하는 방법, 기대되는 결과, 오류 모드 및 정규적인 사용을 설명하는 사용자를 위한 문서입니다.
- 운영 매뉴얼: 이러한 문서들은 운영자가 시스템을 운영하는 방법(구성, 배포, 모니터링 등) 및 시스템이 예상대로 작동하지 않을 때 시스템 문제 해결 방법을 설명하는 운영자를 위한 문서입니다.
위에서 언급된 세트를 벗어나는 일부 문서들은 여전히 유용할 수 있지만 일부 상황에서 필요에 따라 생성됩니다. 이러한 것들은 아키텍처 의사 결정 레코드(희생의 기록과 의사 결정을 문서화), 기술 제안서(일부 프로젝트에서는 문서 또는 엔지니어링 작업 추적 시스템의 티켓일 수 있음), 사용자 스토리(지원되지 않는 기능 또는 지원되어야 하는 기능의 명세), 결함 보고서 또는 변경 요청(형식적인 프로세스에서 이전에 동의된 또는 제공된 기능에서 벗어나는 사항을 문서화하기 위해 필요한 장소들)과 같은 것입니다. 저는 이러한 내용을 다루지는 않겠지만, 아래에서 다룰 이유와 동일한 이유로 이러한 것들이 귀중하다는 점을 안심하고 이해하실 수 있습니다.
문서 작성의 목적은 무엇인가요?
이것은 많은 사람들이 묻기를 두려워하거나 어떤 관점을 선택하거나 선택하지 않았습니다. 여기에서 효과적인 문서 작성이 추구할 가치가 있는지를 설득할 수 있는 관점을 제시하고자 합니다.
- 무엇 때문에 그렇게 되는지를 명시하는 것이 추론하는 것보다 낫습니다. 어떤 알고리즘이 사용되는 이유를 설명하거나 필드의 순서가 왜 중요한지, 또는 왜 그것이 그 이름으로 지어졌는지, 어떤 대체 이름이 사용될 수 있었는지 설명하는 것은 시스템을 읽고 이해하는 것을 더 쉽게 만듭니다.
- 소프트웨어 엔지니어링과 같은 팀 스포츠에서는 동일한 페이지에서 있고 유지하는 것이 팀이 공동 목표에 집중할 수 있도록 허용합니다. 코드 구조를 이해하지 못하는 팀이나 서로의 작업을 방해하고 의사 소통 라인을 유지하지 않는 팀에 속해 있는 것보다 나쁜 것은 없습니다. 시 기존 구조의 목표를 먼저 이해하지 않고 60%의 코드를 다시 작성하는 사람 때문에 팀의 동기를 약화시키고 독성이 있는 팀 환경을 만들어냅니다. 또는 그렇게 하고도 변경 사항을 왜 전달해야 하는지 전달하지 않을 때도 마찬가지입니다. 동일한 페이지에 있으면 모든 사람이 포함되고 서로 작업하는 방향을 정렬할 수 있으며 이는 팀워크와 협력을 효과적으로 촉진합니다.
- 문제, 가능한 해결책 및 가치 전달 계획을 문서화하여 모두가 성공을 이루도록 설정합니다. 최소한, 문제가 무엇이며 당신과 팀이 풀려고 하는 문제와 사용 가능한 해결책, 선택한 해결책이 무엇인지 명확히하면 읽는 이들(팀, 이해관계자, 경영진, 고객)이 어떻게 가치를 전달할 것인지 이해됩니다. 스테이크홀더가 동의하도록 써내려갈 수 없다면, 코딩에 뛰어들어서 모든 일이 잘 될 것이라고 기대하는 것만으로는 충분하지 않습니다. 희망은 전략이 아닙니다.
이것들은 문서 작성이 왜 중요한지에 대한 몇 가지 이유입니다. 더 많이빠뜨린 이유가 많을 것이라고 확신합니다. 하지만 다음 섹션에서는 위에서 제시한 이유에 따라 효과적인 문서 작성이 어떻게 보이는지 설명하려고 합니다.
효과적인 문서 작성의 특징은 무엇인가요?
효과적인 문서 작성의 네 가지 주요 특징이 있습니다:
- 명확성
- 완성도
- 일관성
- 관련성 / 최신 정보
이러한 요소들은 문서의 목적 대상 대중의 관점에서 측정되어야 합니다. 위에서 언급한 것처럼, 소프트웨어 엔지니어링 문서에는 일반적으로 세 가지 주요 대상이 존재합니다:
- 사용자
- 소프트웨어 엔지니어
- 운영자
이러한 대상들이 동일한 사람들의 집합일 수 있습니다 (예: 소프트웨어 엔지니어를 대상으로 하는 소프트웨어 도구가 자체 시스템을 실행하는 경우도 있지만), 그들의 관심사는 명확히 정의되어 있고 서로 독립적으로 만들어질 수 있습니다.
여러 해 동안 배운 효과적인 글쓰기의 한 원칙은: 청중을 염두에 두세요.
다음 섹션에서는 각 주요 속성을 다루고 귀하의 문서가 효과적인지를 어떻게 확인할 수 있는지 설명하겠습니다.
명확함
무언가가 명확하다는 것은 모호하지 않고 오해의 여지가 없음을 의미합니다.
명확하게 쓰기 위해서는 단일한 초점을 가져야하며, 그 의미를 전달할 때 주의를 산만하게 하지 않는 것이 중요합니다.
가능한 한 용어를 지양하고, 사용할 때는 그 의미를 명확히 하기 위해 용어를 한 곳 (용어 해설집과 같은)에서 한 번 정의하는 것이 좋습니다.
내가 문서를 명확하게 작성할 수 있도록 돕기 위해 하고 있는 몇 가지 활동은 다음과 같습니다:
- 대상 독자에게 문서를 테스트하고 명확성에 대한 피드백을 받습니다.
- 문서에 대한 비판을 받기 위해 신뢰할 수 있는 사람들에게 조언을 구합니다. 가능한 명확성을 목표로 하는 것이 좋습니다. 문제나 해결책 영역에 깊게 친숙하지 않은 다른 사람이 이 도움이 되며, 내 편향과 공감대를 식별하고 미래의 문서 작성 기술을 향상시키는 데 도움이 됩니다.
- 동일한 문장/단락의 다른 버전을 작성하고, 대상 독자의 관점을 활용하여 어떤 것이 더 명확할지 확인한 후 선택합니다. 이 과정은 시간이 많이 소요되지만, 과거에는 더 나은 품질의 결과를 이끌어냈다는 것을 알았습니다.
명확하게 쓰는 목표는 이해하기 쉽도록 매끄럽게 만드는 데에 있습니다. 명확하게 작성된 문서는 문서를 읽는 사람들이 문서에 대한 좋은 이해와 처음보다 적은 질문을 가지게 될 때 효과적입니다.
문서를 읽은 후에도 사람들이 여전히 질문을 하고 있다면, 여전히 문서가 충분히 명확하지 않은 것입니다.
완성도
문서는 의도된 대상 청중의 관점에서 솔루션의 모든 관련 부분을 다룰 때 완료됩니다.
관련 부분을 알아내는 것은 대상 대상에게 어렵지 않을 것입니다. 그들과 소통할 수 있는 개방된 커뮤니케이션 라인을 갖고 있으면 괜찮아요. 고객을 상상하는 것은 어려울 수 있으니, 실제 고객과 대화하는 것이 더 나은 방법입니다. 혹은 소프트웨어 엔지니어로서의 관점만 얻고 다른 모든 소프트웨어 엔지니어가 당신처럼 같은 우려를 가질 것으로 가정하는 것은 완전한 문서 작성을 이룰 가능성이 낮습니다.
이것은 시간이 많이 소요될 수 있고 일반적으로 많은 반대가 이루어지는 곳입니다. 소프트웨어 엔지니어는 보통 문서 작성에서 능가하지 않는데, 이는 문제 해결 연습으로 보이지 않기 때문입니다. 그러나 문제를 해결해야 할 문제로 대해 다룬다면, 대부분의 소프트웨어 엔지니어는 과정을 자동화하거나 한 번에 문제를 해결할 방법을 찾을 것입니다.
Google에서는 공개 인터페이스의 문서화에 매우 높은 표준이 설정되어 있습니다. 내가 수백만 줄의 코드를 보았을 때 함수 문서가 얼마나 좋았는지 매우 놀랐습니다. 더 좋았던 것은, 무언가가 완전하지 않았을 때 누군가가 그것을 문제로 여기고 가능한 빨리 해결하려고 할 것이라는 점이었습니다 (불완전한 창문과 모든 좋은 요소).
대상의 관점에서 몇 가지 핵심 질문에 대한 답을 제공할 때 나의 문서가 완벽하다는 것을 알 수 있습니다:
- 이 해결책의 기능은 무엇인가요? 만약 이것이 코드의 함수라면, 어떤 인수들이 있고, 결과에 어떤 영향을 주며, 실패하는 경우는 어떤 것이며, 무엇을 할 수 있는지 알려주세요. 만약 도구라면, 어떤 옵션이나 명령어가 있으며, 입력은 어떻게 받는지, 어떤 형식으로 받는지, 출력은 어떤 형태인지 등을 말씀해주세요.
- 추가 정보가 필요한 경우 어디서 더 찾을 수 있나요? 예를 들어, 명령줄 도구의 경우
-help
옵션이나 보다 포괄적인 문서로 이어지는 링크가 있을 수 있습니다. 사용자 매뉴얼이 모든 가능한 옵션을 다루지 않는 경우, 소스 코드 내 주석으로부터 생성된 온라인 옵션 문서가 도움이 될 수 있습니다. - 이 해결책은 어떻게 작동하나요? 운영에 필요한 종속성이 있는지, 특정 하드웨어/소프트웨어 패키지에서만 작동하는 기능이 있는지 알려주세요. 소프트웨어 엔지니어가 아니더라도 사용자가 특정 소프트웨어가 어떻게 작동하는지 알고 싶어 할 수 있습니다. 이 정보는 문서의 일부로서 완전성을 갖추어야 합니다.
- 이 소프트웨어는 누구를 위해 만들어졌나요? 명시적으로 문서화하는 것이 완성도에 중요합니다.
- 언제 이 소프트웨어를 사용해야 하나요? 다른 말로 하면, 이 소프트웨어가 해결하려는 문제는 무엇인가요?
- 왜 이 소프트웨어가 존재하나요? 이것은 트레이드오프에 관련이 있습니다. 이것은 요구 사항을 충족시키지 못했기 때문에 구축되었나요? 그 요구 사항은 무엇이었나요(문서화해 주세요)?
소프트웨어 엔지니어들이 여기를 보고 "너무 어렵다; 문제에 대한 80/20 솔루션이 있나요?" 라고 말할 수도 있습니다. 제 답은 네이다 - 그러나 어떤 20%의 문서가 80%의 가치를 얻을 수 있는지 아는 것은 모든 고려 사항을 다 다루는 것보다 어렵습니다.
문서가 완성되기 위해서 반드시 길어야 하는 것은 아닙니다.
일관성
효과적인 문서 작성은 일관된 단어, 스타일, 그리고 어조를 사용합니다.
Google에서는 코드뿐만 아니라 공개 인터페이스에 대한 문서 작성도 다루는 스타일 가이드가 있었습니다. 이는 모두가 따르고 서로가 책임을 질 수 있는 일관된 지침이 있어 문서 읽기와 쓰기에 큰 도움이 되었습니다. 그곳에서 가장 소중히 여겼던 것은 이 커뮤니티와 문화적 측면이었습니다.
독창성과 창의성을 가질 여지가 있지만 (예: 유머나 장난이 섞인 사용 설명서를 만들 수 있음) 문서 작성 방식은 일관되었습니다 - (예: 모든 프로젝트는 README.md를 포함해야 함). 이런 일관성으로 인해 각 문서를 서로 연결시키고 검색 가능하게 만듭니다. 다른 프로젝트에 의존하는 경우 문서 링크나 구현을 따라서 어떤 관련성이 있는지 확인할 수 있습니다.
일관성 있는 자기 일관성은 설계 문서와 같이 독립적인 문서에 중요합니다. 이는 문서를 읽는 사람이 같은 의미를 가진 다른 단어로 산만해지는 일을 방지하기 때문입니다. 여러 문서에서 같은 단어를 사용하면 관련 분야를 이해하는 독자에게 혼란을 줄일 수 있습니다.
문서가 사용하는 용어에 혼란을 느끼지 않을 정도로 일관성 있게 작성했다면, 그 문서는 정말 좋은 문서입니다.
적합성 및 최신 정보 유지
문서가 오래되어 있을 때는 더 좋지 않습니다.
최선의 경우, 문서는 약간 잘못되어 있을 수 있고, 최악의 경우 독자를 활성으로 오도할 수 있습니다. 제 경력에서 여러 번 문서가 오래되었다는 느낌을 받아 와서 그냥 그 부분을 제거하도록 pull request를 보내야겠다고 느낀 적이 있습니다. 다행히도, 제가 직접 그렇게 한 번 했을 때 프로젝트 소유자들이 감사했습니다.
문서화의 가치는 정확성과 관련성을 갖추었을 때 나타납니다. 문서가 구현의 현실을 설명하지 않을 때, 그것은 더 이상 정확하거나 관련성이 없게 됩니다. 마찬가지로, 문서가 프로젝트가 가는 방향과 다를 때, 그것은 더 이상 정확하거나 관련이 없게 됩니다. 이러한 경우 모두, 문서화를 정확하고 관련성있게 유지하는 것은 소프트웨어 공학의 정상적인 과정의 일부여야 합니다.
C++ 기반의 그래프 서버를 다시 작성하는 노력 속에서, 우리는 구현을 변경할 때마다 문서를 수정하는 것을 보장했습니다. 우리는 Doxygen을 사용하여 문서와 UML 관계를 생성하고 코드와 함께 보관하여 업데이트했습니다. 우리는 용어, 프로젝트 목표 및 이미 제공한 기능을 정의한 위키가 있었습니다. 성능 지표도 위키에 포함되어 있었습니다. 프로덕션 테스트 및 결과도 거기에 문서화되었습니다.
누군가가 프로젝트에 참여할 경우, 문서가 충분히 갖추어져 있어서 그들이 들어가서 자신의 학습속도에 맞게 생산적으로 활동할 수 있도록 보장했습니다. 물론, 우리는 그들을 도와주었지만, 우리는 문서화를 통해 운영팀, 제품팀, 엔지니어링팀 다른 구성원 및 경영진 사이에 의사소통하는 데 많이 의지했습니다.
Google에서는 코드베이스에 호스팅된 문서의 마지막 업데이트 시간을 자동으로 확인하고 업데이트가 필요한 팀에 버그를 보고할 수있는 시스템을 사용할 수 있었습니다. 이는 문서 관리를 시스템의 유지보수의 일환으로 만들어 존중받아야 할 대상으로 만듭니다.
될 수 있습니다. 문서에서 바라야 할 것은 현실을 반영하는 것입니다.
오픈 소스에서의 문서화
오픈 소스 프로젝트의 문서화와 가치에 대한 핵심 성공 사례는 효과적인 문서의 유무에 따라 오픈 소스 프로젝트가 성공하거나 실패하는 것입니다.
Rust, Python, OCaml, Zig, C#, Java 및 LLVM 컴파일러 도구 체인과 같은 프로젝트의 문서 품질은 사용자와 소프트웨어 엔지니어에게 가치를 제공하는 종류의 문서화 사례입니다.
예를 들어, Cloud Native Computing Foundation (CNCF)의 프로젝트들은 만나야 하는 문서 품질 기준이 있습니다. 이러한 이유로, 대부분의 현대 소프트웨어 엔지니어링 프로젝트를 지원하는 이러한 기본적인 기능들은 유지 및 운영 부담을 줄이기 위해 높은 품질의 문서가 필요합니다. Kubernetes, gRPC 및 Istio 같은 프로젝트는 매우 잘 쓰여진 문서를 갖고 있어 개발자들이 최신 시스템 아키텍처를 빠르게 익힐 수 있도록 도와줍니다.
이러한 시스템들에 대한 고품질 문서에 접근할 수 없고 코드만으로 배워야 한다면 어떨까요? 저라면 그런 작업 환경에서 일을 수행해야 한다면 다른 산업으로 이직할 것 같습니다!
코드가 공개되어 있음에도 불구하고, 이러한 프로젝트 관리자 및 그 주변 커뮤니티들이 효과적인 문서화를 중요시하고 그것에 투자하면서 서비스 대상 청중들을 위해 합리적인 조치를 취하는 것은 훌륭한 센스입니다.
결론
내 약 20년의 경력 동안 문서 작성을 즐기지 않았다고 말한다면 거짓말 할 것입니다. 개인적으로 효과적인 문서 작성은 모든 소프트웨어 엔지니어가 투자해야 할 핵심 기술이라고 믿습니다. 그 가치만큼이나 이 기술이 소프트웨어 엔지니어링의 여러 측면으로 옮겨지는 방법 때문에 그렇습니다.
다른 사람들이 이해할 수 있는 형태로 아이디어를 적을 수 있는 능력이 현대 소프트웨어 엔지니어링의 본질입니다. 소프트웨어 엔지니어링의 팀 스포츠로서, 협력, 문서 작성 및 문제 해결이 코드를 직접 작성하는 것보다 더 중요해질 것입니다. 사실, 현대 소프트웨어 엔지니어링에서 코드를 작성하는 것은 더 이상 중요한 부분이 아닙니다. 아이디어를 작성하고 동료들에게 비평을 받아 계획을 향상시키고, 공유 목표 아래에서 최상의 속도로 실행함으로써 가치를 창출하는 과정이 중요합니다.
효과적인 문서 작성이 우선순위로 취급될 때, 오픈 소스 소프트웨어에서 긍정적인 결과를 볼 수 있습니다. 동일한 모델을 따라 현대 소프트웨어 엔지니어링을 수행하는 데 팀과 당신을 막는 것은 없어야 합니다.
원한다면, ChatGPT에게 문서 작성을 맡겨볼 수도 있을 거예요! :)
후속 글
이 시리즈의 기사를 즐겨 보고 계셨기를 바랍니다. 이 글을 즐겼고 이전 두 부분을 아직 읽지 않으셨다면 여기에서 찾을 수 있습니다:
- Part 1: 시스템 디자인
- Part 2: 테스팅
또한 소프트웨어 엔지니어링에 대해 쓴 글도 있으니, 그것도 마음에 들 수 있을 것입니다.
- 주요 소프트웨어 엔지니어는 무엇인가요?
- 시니어 소프트웨어 엔지니어는 무엇인가요?