소프트웨어 엔지니어링 재고: 유지보수성에서 왜 실패했는가

발행: (2025년 12월 15일 오전 06:20 GMT+9)
13 min read
원문: Dev.to

Source: Dev.to

저는 유지보수 가능한 애플리케이션을 만들기 위한 현재 소프트웨어 엔지니어링 상태에 대해 강한 의견을 가지고 있습니다. 실패했고, 변화를 시도해야 할 때입니다. 모든 것을 버리고 새로 시작하자는 것이 아니라 진화하자는 이야기입니다. 오늘날 소프트웨어 엔지니어링에는 보존할 수 있는 좋은 점들이 많이 있습니다. 하지만 잡곡과 찌꺼기를 구분하기 전에, 현재 접근 방식이 왜 통하지 않는지 먼저 이해해야 합니다.

현대 소프트웨어 엔지니어링의 문제

2000년대 이후 여러 작업이 이 분야에 큰 영향을 미쳤습니다: Refactoring¹, Design Patterns², Domain‑Driven Design³, Clean Code⁴, Clean Architecture⁵, SOLID 원칙⁶, 그리고 Hexagonal⁷, Microservices⁸와 같은 아키텍처 스타일. 이는 유지보수성을 위한 모든 소프트웨어 엔지니어링을 대표하는 것은 아니지만, 가장 영향력 있는 작업들을 포함하고 있어 현 상황을 충분히 조망할 수 있게 해줍니다. 이렇게 인상적인 지적 기반에도 불구하고, 실제 현장에서는 무언가가 제대로 작동하지 않고 있습니다.

얼마 전 저는 Adam Tornhill이 진행한 “Prioritizing Technical Debt as if Time & Money Matters”⁹ 라는 강연을 보았습니다. 그는 컨설팅을 맡은 회사 팀이 특정 서비스가 유지보수가 어렵다고 불평한 사례를 소개했습니다. 외부 컨설턴트인 그가 코드베이스를 분석하고 팀이 진행 중인 다른 프로젝트와 비교했을 때, 코드 품질에서 객관적인 차이를 찾지 못했습니다. 하지만 팀이 불평한 프로젝트는 팀 자체가 개발한 것이 아니라, 원래 팀이 해체된 뒤 인수된 것이었습니다.

이 사례는 중요한 점을 보여줍니다: 문제는 코드베이스 자체가 아니라, 코드베이스가 깊은 사회·조직적 문제를 드러내고 있다는 것입니다. 전문적으로 소프트웨어를 만드는 일은 근본적으로 사회적 행위입니다. 우리는 다른 사람과 함께 소프트웨어를 만들고, 우리의 코드는 그 관계의 기능 부전이나 건강 상태를 반영합니다. 이는 1960년대부터 제시된 Conway’s Law¹⁰이 시사하는 바와 같습니다. 이 깨달음은 제가 가장 선의의 의도를 가진 실천들을 다시 생각하게 만들었습니다.

원칙과 실천 사이의 격차

예를 들어 Domain‑Driven Design을 살펴봅시다. 이 작업은 Ubiquitous Language¹¹라는 개념을 도입해, 도메인 언어가 사회적 상호작용에서 자연스럽게 형성된다는 점을 강조했습니다. 하지만 실제 구현상의 어려움을 다루지는 못했습니다. 우리는 기술·비즈니스 간 커뮤니케이션 문제를 해결하기 위한 개념적 해결책으로 Ubiquitous Language를 가지고 있지만, 구현에 대한 실질적인 가이드는 부족합니다:

  • 비즈니스 이해관계자를 그 과정에 참여시키려면 어떻게 설득해야 할까?
  • 평균 규모 조직의 일반 개발자가 전체 팀 혹은 여러 팀이 소프트웨어를 구축하는 방식을 바꿀 권한이 있을까?
  • 제한점은 무엇인가?
  • 현재 코드베이스에 이미 녹아 있는 레거시 비유비터스 언어는 어떻게 다루어야 할까? 위험 요소는 무엇인가?

이것은 수사적 불만이 아니라, 실무 엔지니어가 매일 마주하는 실제 장애물입니다. 그러나 우리에게 영향력 있는 저작물들은 이런 문제들을 거의 다루지 않습니다. 우리가 가진 지식은 원칙을 전제와 실제 적용에 영향을 미치는 제약 조건으로부터 분리시켜 버립니다.

가장 근본적인 원칙에서도 같은 문제가 나타납니다. 함수가 “한 가지 일만” 하도록 하는 clean‑code 원칙¹²(또는 SOLID의 Single Responsibility Principle¹³)을 적용하려 할 때, 적용 가능성에 대한 난관에 부딪힙니다. 책임이란 무엇인가? “한 가지”란 무엇인가? “변경 이유”란 무엇인가? 철학자들조차 이 질문을 두고 논쟁합니다. 수천 년 동안 이 문제를 다루어 온 ontology¹⁴라는 철학 분야가 존재합니다.

두 개의 서로 다른 객체를 예로 들어 “단일” 책임·대상·변경 이유를 달성하는 것이 왜 쉬운 일이 아닌지 살펴봅시다. 유지보수 관점에서 데스크톱노트북을 비교합니다:

  • 데스크톱 – 키보드가 고장 나면 고장 난 키보드를 뽑고 교체하면 됩니다. 데스크톱은 노트북에 비해 책임이 적습니다.
  • 노트북 – 키보드가 내장돼 있어 교체하려면 전체 장치를 분해해야 하므로 훨씬 어렵습니다.

데스크톱 예시조차도 질문을 남깁니다: 키보드가 **“한 가지”**인가? “A”키만 고장 났다면 전체 키보드를 교체할까, 해당 키만 교체할까? 키 자체가 **“한 가지”**인가, 아니면 스위치와 다른 부품으로 이루어진 것인가? 더 확대하면 아원자 수준까지 파고들게 됩니다. 소프트웨어에서도 객체와 모듈은 유사한 딜레마에 직면합니다. 우리는 추상화를 무한히 확대해 비트 수준까지 갈 수 있지만, Single Responsibility Principle어떤 추상화 수준이 필요하고, 조직·사회적 제약 하에서 어느 수준까지 다룰 수 있는지를 알려주지 않습니다.

마이크로서비스가 얼마나 “마이크로” 해야 하는지를 정의하려 할 때도 비슷한 문제가 발생합니다. 목표는 “단일” 혹은 “마이크로” 자체가 아니라, 책임의 수와 “대상”의 크기를 조정해 특정 목적을 달성하는 것입니다. “단일 대상”을 목표 자체로 삼는 것은 원칙이 될 수 없습니다. 많은 숙련된 실무자는 이미 이를 인지하고 있지만, 이론은 이를 형식화하지 못해 경험이 적은 엔지니어를 오도할 수 있습니다.

빠진 기반: 경험적 증거

소프트웨어 엔지니어링은 다른 지식 분야에 비해 역사도 짧고 성장 속도가 빠른 분야입니다. 아직 우리가 필요로 하는 많은 답을 갖고 있지 않으며, 전문가들은 경험을 바탕으로 최선의 결정을 내려야 합니다. 하지만 우리는 더 조직적이고 세밀하게 접근할 수 있습니다.

유지보수성을 위한 소프트웨어 엔지니어링 원칙·실천의 효과와 한계에 대한 데이터 부족이 문제의 핵심입니다. Clean Code, SOLID, DDD, 리팩터링 등 주류 기법에 대한 연구가 더 필요합니다. “내게는 효과가 있었다”는 새로운 기법을 발표하는 것은 가치가 있지만, 그것이 어떤 전제와 조건 하에서 작동했는지를 이해해야 합니다. 대규모 채택에 대한 객관적·경험적 데이터가 없으면 이러한 주장은 가설에 불과합니다. 한 팀에 효과가 있었다고 해서 다른 팀에도 동일하게 적용된다는 보장은 없습니다. 우리는 특정 상황에서 효과가 있거나 없을지를 합리적으로 파악해야 합니다.

제 경험이 이 격차를 보여줍니다. 기업용 웹 애플리케이션(ERP, 농업, 물류 등) 개발에 10년 종사하면서 “Shotgun Surgery”¹⁵와 같은 코드 변경이 배포 지연을 일으킨 적은 없습니다. 여러 곳에 걸쳐 변경이 필요해 번거롭고 느리며 오류 가능성이 높지만, 이는 차단 요인이 되지 않았습니다. 반면, 원래 기여자가 떠난 뒤 아무도 어떻게 작업해야 할지 모르는 코드베이스에 기여하려다 며칠을 허비한 적은 있습니다. 작은 기여를 위해 깊이 파고들어야 했던 그 과정이 큰 장애물이었습니다.

또한, 팀의 준비가 부족한 상황에서 프로젝트 리더가 DDD 도입을 시도해 프로젝트가 지연된 사례도 보았습니다. 제 생각엔 기법과 팀 상황 사이의 불일치가 원인입니다. 이는 경험적 근거의 필요성을 강조합니다: 방법론을 제시하기 전에 준비도, 조직 건강, 기타 제약을 평가해야 합니다.

각주

  1. Martin Fowler, Refactoring (1999)
  2. Erich Gamma et al., Design Patterns (1994)
  3. Eric Evans, Domain‑Driven Design (2003)
  4. Robert C. Martin, Clean Code (2008)
  5. Robert C. Martin, Clean Architecture (2017)
  6. SOLID Principles (Robert C. Martin)
  7. Alistair Cockburn, Hexagonal Architecture (2005)
  8. Microservices Architecture (various sources)
  9. Adam Tornhill, “Prioritizing Technical Debt as if Time & Money Matters” (talk)
  10. Melvin Conway, Conway’s Law (1968)
  11. Eric Evans, Ubiquitous Language (DDD)
  12. Robert C. Martin, Clean Code (2008) – “one thing per function”
  13. Robert C. Martin, SOLID – Single Responsibility Principle
  14. Ontology (philosophical discipline)
  15. Martin Fowler, “Shotgun Surgery” (code smell)
Back to Blog

관련 글

더 보기 »

SOLID 원칙 + 디자인 패턴

!Forem 로고 https://media2.dev.to/dynamic/image/width=65,height=,fit=scale-down,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%...

왜 디자인 패턴?

디자인 패턴은 무작위로, “모두에게 맞는” 방식으로 억지로 조합한 단축키처럼 사용하도록 만든 것이 아니라는 점을 이해하는 것이 중요합니다.