AI와 엔터프라이즈 소프트웨어 개발
요약
AI가 소프트웨어 개발의 패러다임을 바꾸고 있지만, 엔터프라이즈 소프트웨어의 핵심인 '도메인 모델'의 중요성은 여전히 간과되고 있습니다. AI는 빠른 구현을 돕지만, 도메인에 대한 깊은 이해 없이 코드만 양산할 경우 유지보수가 불가능한 기술 부채를 가속화할 위험이 있습니다.
핵심 포인트
- 엔터프라이즈 소프트웨어의 핵심은 구현이 아닌 도메인 이해임
- 도메인 모델 없는 애플리케이션은 유지보수 비용이 교체 비용을 초과함
- AI는 빠른 구현을 가속화하지만 구조적 결함을 은폐할 위험이 있음
- 지속 가능한 소프트웨어를 위해서는 견고한 도메인 모델링이 필수적임
AI는 인터넷 이후 소프트웨어 개발 분야에서 가장 중대한 변화입니다. 이는 AI가 소프트웨어가 할 수 있는 일을 바꾸기 때문이 아니라, 업계가 지난 30년 동안 하나의 선호 사항으로 취급해 온 차이점의 결과를 가속화하기 때문입니다.
어떤 소프트웨어는 오늘 당장 작동해야 합니다. 어떤 소프트웨어는 요구사항과 팀이 바뀌는 동안에도 10년 또는 15년 동안 올바르고 유지보수 가능한 상태로 계속 작동해야 합니다. 이것들은 동일한 엔지니어링 문제가 아닙니다. 단 한 번도 동일했던 적이 없습니다. 첫 번째 경우에 도움이 되는 도구와 관행은 두 번째 경우를 적극적으로 저해합니다. AI는 첫 번째 경우를 그 어떤 인간 개발자보다 더 빠르고 더 잘 수행합니다. AI가 두 번째 경우에 미치는 영향이 바로 이 글의 주제입니다.
엔터프라이즈 소프트웨어의 실제 정의
엔터프라이즈 소프트웨어는 규모, 산업, 또는 기술 스택(Technology stack)에 의해 정의되지 않습니다. 그것은 시간과의 관계에 의해 정의됩니다.
엔터프라이즈 애플리케이션은 오늘 반드시 정확해야 합니다. 비즈니스 도메인(Business domain)이 그 주변에서 진화함에 따라 계속해서 정확성을 유지해야 합니다. 그것을 구축한 팀이 바뀌더라도 살아남아야 합니다. 작성 당시에는 아무도 완전히 예측할 수 없었던 요구사항에 적응해야 합니다. 구현(Implementation)은 주요 과제가 아닙니다. 이해(Understanding) — 즉, 비즈니스 도메인에 대한 정확하고, 내구성이 있으며, 지속적으로 업데이트되는 이해 — 가 주요 과제입니다. 구현은 그로부터 따라오는 것이며, 작업의 더 작은 부분입니다.
이것이 바로 도메인 모델(Domain model)이 작동하는 애플리케이션보다 더 중요한 이유입니다.
그 문장은 대부분의 개발자를 불편하게 만들 것이며, 마땅히 그래야 합니다. 작동하는 애플리케이션(Working application)은 눈에 보이는 결과물 — 즉, 시연되고, 전달되며, 측정되는 대상입니다. 하지만 도메인 모델(Domain model)이 없는 작동하는 애플리케이션은 일회용 품목에 불과합니다. 그것은 공장을 떠날 때는 제대로 작동합니다. 하지만 유지보수(Serviced)를 위해 설계되지 않았습니다. 비즈니스가 그 주변에서 변화할 때 — 그리고 반드시 변화할 것입니다 — 수리 비용이 교체 비용을 초과하게 됩니다. 하지만 단순히 교체할 수도 없습니다. 모델이 없다면, 새로운 버전에서도 동일한 오해들을 더 빠르고 더 확신에 차서 다시 구축하게 될 것이기 때문입니다.
반면에, 작동하는 애플리케이션이 없는 도메인 모델은 토대(Foundation)입니다. 그 토대 위에서 애플리케이션을 작동시키는 것은 더 작은 문제입니다. 그것은 계속해서 제대로 작동할 것입니다. 왜냐하면 그것을 올바르게 유지하는 메커니즘이 여전히 존재하고, 여전히 읽기 쉬우며(Legible), 여전히 정직하기 때문입니다.
오늘을 위해 구축된 소프트웨어와 시간이 지나도 올바른 상태를 유지하도록 구축된 소프트웨어 사이의 이러한 차이 — 이 구분은 항상 존재해 왔습니다. 그것은 항상 구조적인 결과(Structural consequences)를 수반하는 구조적인 선택이었습니다. 다만 그 결과가 눈에 보이지 않았기에 그저 선호도의 문제로 취급되었을 뿐입니다. 비교할 수 있는, 즉 다르게 구축된 동일한 애플리케이션의 버전이 존재하지 않았기 때문입니다. 모델링을 하지 않음으로써 발생하는 비용은 영구적으로 숨겨져 있었습니다.
AI가 그 숨겨짐을 불가능하게 만들지는 못합니다. 반증 불가능성(Unfalsifiability)은 그대로 유지됩니다 — 여전히 비교할 수 있는, 다른 방식으로 구축된 애플리케이션이 존재하지 않습니다. AI가 하는 일은 결과의 축적을 가속화하는 동시에, 코드베이스(Codebase)를 절차적 개발(Procedural development)이 했던 것보다 더 깔끔해 보이게 만드는 것입니다. 이 조합은 이전보다 덜 위험한 것이 아니라, 오히려 더 위험합니다.
보이지 않는 붕괴
엔터프라이즈 소프트웨어(Enterprise software)에는 거의 아무도 정확하게 진단하지 못하는 실패 모드(Failure mode)가 있습니다. 그 이유는 단순합니다. 그것을 진단하려면 존재하지 않는 참조점(Reference)이 필요하기 때문입니다.
엔터프라이즈 시스템이 유지보수하기 어려워질 때 — 기능 구현에 예상보다 더 많은 시간이 걸리고, 버그가 예상보다 더 광범위하게 영향을 미치며, 팀 규모는 커지는데 인도(Delivery) 속도는 개선되지 않을 때 — 그 진단은 거의 항상 동일합니다. 이것이 바로 엔터프라이즈 개발의 모습이라는 것입니다. 복잡한 도메인(Domain). 거대한 코드베이스(Codebase). 누적된 기술 부채(Technical debt). 이에 대해 제시되는 해결책은 더 많은 개발자, 더 많은 프로세스, 더 많은 도구입니다.
진정한 진단을 위해서는 다음과 같은 질문을 던져야 합니다. 만약 이 시스템이 처음부터 풍부한 도메인 모델(Domain model)을 중심으로 구축되어 동일한 기간 동안 유지보수되었다면 어떤 모습이었을까? 그 버전은 구축된 적이 없습니다. 비교 대상이 존재하지 않습니다. 따라서 시스템의 퇴보는 이를 방지할 수 있었던 구조의 부재가 아니라, 엔터프라이즈의 복잡성 때문인 것으로 치부됩니다.
업계가 엔터프라이즈 개발의 자연스러운 어려움으로 오독한 것은, 대부분의 경우 망가진 PDCA 사이클의 결과입니다. 계획(Plan), 실행(Do), 점검(Check), 조치(Act). 엔터프라이즈 소프트웨어에서 점검(Check) 단계는 무엇이 인코딩되었는지 찾아내고, 이를 현재의 이해와 대조하여 검증하며, 이를 업데이트할 수 있는 능력을 요구합니다. 이를 위해서는 시스템의 필수적인 복잡성(Essential complexity)이 가시적이어야 하고, 소유권이 명확해야 하며, 한 곳에 모여 있어야 합니다.
절차적 개발(Procedural development)은 이 사이클을 느리게 만드는 것이 아니라, 파괴합니다. 올바른 위치가 아닌 편리한 곳에 존재하는 각각의 로직, 중복된 규칙, 서비스 클래스(Service classes)에 흩어져 있고 해당 개념(Concept)에 의해 관리되지 않는 각각의 동작들은 — 점검(Check) 단계에 필요한 지도의 조각들을 하나씩 제거합니다. 결국 지도는 사라집니다. 기존 기능이 실제로 무엇을 하는지 아무도 확신하지 못한 채, 새로운 요구사항이 기존 요구사항 위에 덧씌워집니다. 모순이 쌓여갑니다. 시스템은 하부에 일관된 구조 없이, 요청되었던 모든 것들이 시간 순서대로 기록된 기록물이 되어버립니다.
이것은 엔터프라이즈의 복잡성(complexity)이 아닙니다. 내일도 살아남을 수 있는 형태로 이해(understanding)를 인코딩하지 않은 채, 오늘만을 위해 구축한 결과입니다. 그리고 이는 언제나 일어날 수밖에 없는 일이었습니다. 절차적 코드(procedural code)에는 Check 단계를 계속 유지할 수 있는 메커니즘이 없기 때문입니다.
사이클을 지속시키는 두 가지 관행
이러한 붕괴를 방지하는 두 가지 관행이 있습니다. 이것들은 방법론(methodology)이 아닙니다. 인증을 받을 수도 없습니다. 이것들은 규율(disciplines)이며, 각각 정밀한 역할을 수행하며 순차적이고 상호 의존적입니다.
1. UI: 유비쿼터스 언어(Ubiquitous Language)의 검증
첫 번째 관행은 어떤 프로젝트에서든 첫 달에 UI를 구축하는 것입니다. 이는 최종 사용자나 고객을 위한 것이 아니라, 개발자와 도메인 전문가(domain expert)가 실제로 동일한 것에 대해 이야기하고 있는지 확인하기 위한 일차적인 도구로서 구축하는 것입니다.
이를 위해서는 즉각적인 명확화가 필요합니다. 명확한 최종 사용자 인터페이스가 없는 프로젝트—데이터 파이프라인(data pipelines), 처리 엔진(processing engines), 통합 계층(integration layers)—에서의 본능은 UI를 완전히 미루거나 건너뛰는 것입니다. 그 본능은 매우 구체적이고 중대한 방식으로 잘못되었습니다. UI는 인도물(deliverable)이 아닙니다. 그것은 유비쿼터스 언어(ubiquitous language)—전체 시스템이 정확해야 함에 의존하는 개발자와 도메인 전문가 사이의 공유된 어휘—를 측정하는 척도입니다.
비즈니스 소유자 및 기능 애플리케이션 관리자들과 함께 소프트웨어를 구축해 온 25년 동안, 거의 모든 의미 있는 논의에서 동일한 문장이 등장했습니다. "맞는 말 같긴 한데, 실제로 작동하는 것을 보고 싶습니다." 이것은 상상력의 실패가 아닙니다. 도메인 전달(domain transfer)의 매체로서 언어가 가진 한계에 대한 정직한 진술입니다. 두 사람은 같은 단어를 사용하면서도 서로 다른 의미를 뜻할 수 있습니다. 그들은 설명에는 동의하면서도, 그 설명이 무엇을 묘사하는지에 대해서는 완전히 의견이 다를 수 있습니다. 그러한 불일치는 대화 중에는 보이지 않습니다. 하지만 화면 위에서는 부정할 수 없습니다.
UI는 도메인 전문가(domain expert)가 직접 평가할 수 있는 형태로 개념을 강제합니다. 개발자가 _주문(order)_이라고 부르는 개념과 비즈니스 전문가가 _주문(order)_이라고 부르는 개념이 동일한 것을 가리키는지 여부는 화면을 통해 확인할 수 있습니다. 개발자가 선형적인 시퀀스(linear sequence)로 모델링한 흐름과 비즈니스 전문가가 병렬 상태(parallel states)의 집합으로 이해하는 흐름이 일치하는지 여부 또한 화면을 통해 확인할 수 있습니다. 화이트보드 세션도, 요구사항 문서도, 스프린트 리뷰(sprint review)도 도메인 전문가가 직접 탐색할 수 있는 작동하는 인터페이스만큼 정밀하고 즉각적인 검증을 제공하지 못합니다.
소프트웨어 개발에서 개념적 사고(Conceptual thinking)는 진정으로 희귀합니다. 개발자들은 기술된 동작을 구현하도록 훈련받았을 뿐, 그 기술을 만들어낸 정신 모델(mental models)을 재구성하도록 훈련받지는 않았습니다. UI는 구조적으로 이를 보완합니다. UI는 도메인 모델(domain model)을 가시화하고, 따라서 반증 가능하게(falsifiable) 만듭니다. 이는 도메인 전문가가 당신이 자신을 제대로 이해했는지 여부를 말해줄 수 있는 유일한 조건입니다.
UI가 반드시 세련될 필요는 없습니다. UI는 작동해야 하며, 프로젝트의 수명 동안 그 자체로 유지보수 부담이 되지 않는 의미론적 HTML(semantic HTML)로 구축되어야 합니다. UI의 목적은 프레젠테이션(presentation)이 아니라 검증(verification)입니다.
UI는 도메인을 올바르게 학습하는 방법입니다. 이는 이후에 이어지는 모든 과정의 입력값입니다.
2. 도메인 모델: 학습한 내용을 지속 가능하게 인코딩하기
두 번째 관행은 학습한 내용을 풍부한 도메인 모델(domain model)로 인코딩하는 것이며, 여기서 소프트웨어 개발의 가장 오래된 교훈이 가장 중대한 형태로 적용됩니다.
함께 있어야 할 것들은 같은 곳에 두어, 그 누구도 무언가가 어디에 있는지 설명할 필요가 없게 만드십시오.
이것이 천 피스 퍼즐과 25 피스 퍼즐의 차이입니다. 시스템에서 주문이 어떻게 처리되는지는 Order 도메인 객체(domain object)에서 찾을 수 있습니다. 단 한 곳에 존재하며, 중복되지 않은 로직, 모순되지 않는 로직을 갖습니다. 새로운 개발자, 새로운 요구사항, 컴플라이언스 감사(compliance audit) — 이 모든 것들은 동일한 곳으로 가서 동일한 답을 찾게 됩니다.
도메인 모델 (domain model)은 비즈니스 도메인 내에서 각각 정의된 역할을 수행하고, 그 역할에 수반되는 책임을 갖는 객체들의 집합입니다. 단순히 메서드가 덧붙여진 데이터 구조가 아닙니다. 자신이 무엇을 책임져야 하는지 알고, 스스로의 규칙을 강제하며, 자신의 동작 (behavior)을 지니는 객체들입니다. 취소된다는 것이 무엇을 의미하는지 아는 주문 (Order). 트랜잭션 경계 (transactional boundary)를 소유하며 — 현재 사용자, 활성 역할, 그리고 종료 시점에 실행될 지연된 결과들을 운반하는 상호작용 (Interaction). 자신의 평가를 규정하는 규칙을 소유하는 KYC 엔티티 (entity).
이것이 PDCA 사이클을 살아있게 만드는 핵심입니다. 점검 (Check) 단계는 요구사항이 변하고 세 번의 팀 교체가 일어난 10년 후에도, 실행된 (Done) 내용에 여전히 도달할 수 있습니다. 도메인 모델은 지도입니다. 지도가 정직하고 최신 상태를 유지하는 한, 사이클은 돌아갑니다. 새로운 이해가 제 자리를 찾게 됩니다. 모델은 시간이 흐를수록 모호해지는 것이 아니라 더욱 진실해집니다.
이러한 구조의 결과 중 거의 논의되지 않는 것은, 이것이 무료로 제공하는 이점입니다. 도메인 모델이 자신의 동작을 소유하고 상호작용 (Interaction)이 트랜잭션 경계를 소유할 때, 실패한 작업은 완전히 롤백 (rollback)됩니다 — 데이터베이스 변경, 아직 전송되지 않은 이메일, 아직 발생하지 않은 후속 결과까지 말입니다. JDBC 트랜잭션 롤백은 원시적인 수준입니다. 일관성 (consistency)은 구조적입니다. 작성해야 할 보상 로직 (compensation logic)도, 구현해야 할 사가 패턴 (saga pattern)도, 사후에 실행할 일관성 검증 (consistency verification)도 없습니다. 보장은 모델로부터 자연스럽게 발생합니다.
도메인 모델은 당신이 올바른 일을 무기한으로 계속할 수 있게 하는 방법입니다. 그것은 시스템에 대한 문서가 아닙니다. 그것은 가장 정직하고 내구성 있는 형태의 시스템 그 자체입니다.
두 요소 사이의 관계
이 두 가지 관행은 정밀한 방식으로 순차적이며 상호 의존적입니다.
도메인 모델 (domain model) 없는 UI는 일관성 없이 인코딩된, 올바른 이해를 산출할 뿐입니다. 도메인 전문가 (domain expert)는 언어를 확인했습니다. 개발자는 도메인을 이해했습니다. 그러고 나서 그것을 3년 뒤에는 아무도 찾거나 따라갈 수 없는 방식으로 서비스 클래스 (service classes) 전반에 흩뿌려 놓았습니다. 그 이해는 올바랐지만, 결국 코드베이스 (codebase)로, 여러 레이어 (layers)를 거쳐, 프레임워크 컨벤션 (framework conventions)을 통해 — 다음 개발자가 이를 재구성할 수 없을 때까지 — 부식되어 버립니다.
UI 없는 도메인 모델은 틀렸을지도 모르는 무언가에 대해 응집력 있는 모델을 생성합니다. 우아하고, 추적 가능하며, 내부적으로 일관되지만, 외부적으로는 어긋나 있습니다. 개발자의 해석이 실제로 알고 있는 사람과 대조하여 검증된 적이 없기 때문입니다.
이 둘은 함께 자기 수정적인 사이클 (self-correcting cycle)을 형성합니다. UI는 도메인 전문가가 실제로 의미하는 바를 표면화합니다. 도메인 모델은 그 의미를 내구성 있게 인코딩 (encode)합니다. UI는 인코딩된 의미를 다시 도메인 전문가에게 표면화하여 검증을 받습니다. 이 사이클은 시작 단계뿐만 아니라 애플리케이션의 수명 전반에 걸쳐 자가 지속됩니다.
이것이 바로 도메인 모델만으로도 생존할 수 있는 이유이기도 합니다. 약간 틀린 모델은 여전히 수정 가능합니다. 왜냐하면 그 틀림이 눈에 보이고 위치를 찾을 수 있으며, PDCA 사이클이 여전히 작동하고 있기 때문입니다. 하지만 UI만으로는 생존할 수 없습니다. 내구성 있게 인코딩되지 않은 올바른 이해는 그것을 보유했던 사람들과 함께 사라집니다.
한 가지 관행은 올바른 일을 수행하고 무엇이 올바른 일인지 발견하는 것을 최적화합니다.
다른 한 가지 관행은 그 발견을 가능한 한 왜곡되지 않는 형태로 기록합니다 — 오늘의 팀을 위해, 내일의 유지보수 담당자를 위해, 그리고 아직 아무도 생각하지 못한 요구사항 (requirements)을 위해 말입니다.
업계가 대신 구축한 것
이 두 가지 관행이 없다면, 엔터프라이즈 소프트웨어 (enterprise software)는 조용히 실패하지 않습니다. 팀은 마찰을 느낍니다. PDCA 사이클이 깨집니다. 그리고 업계는 특유의 방식으로, 그 증상들을 관리하기 위한 아키텍처 (architectures)를 구축했습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기