소프트웨어의 본질을 드러내는 변경성·복잡성·비가시성
소프트웨어의 변경성·순응성·무형성·복제성·비가시성·복잡성·비마모성을 개발과 운영 관점에서 정리하고 아키텍처, 테스트, 관측 가능성에 미치는 영향을 설명합니다.
2026-08-14 · 최초 발행 2026-04-17
물리적 제품과 다른 소프트웨어의 성질
소프트웨어는 논리적 개념으로 존재하며 전자적 신호의 형태로 저장되고 실행된다. 물리적 형태가 없다는 점은 단순한 차이가 아니다. 개발 방식, 유지보수 전략, 품질 관리 방식까지 하드웨어와 다른 접근을 요구한다.
소프트웨어의 특성은 물리적 성질, 생산 방식, 진화 가능성, 그리고 내부 복잡성으로 나눠 볼 수 있다. 무형성·비가시성·비마모성은 물리적 성질에 속하고, 복제성은 생산적 특성이다. 변경성과 순응성은 소프트웨어가 계속 진화하는 이유를 설명하며, 복잡성은 시스템 내부에 내재한 과제다.
변경 가능한 산출물은 설계와 테스트를 요구한다
소프트웨어는 배포 뒤에도 버그를 고치고 기능과 성능을 개선할 수 있다. 하드웨어 결함은 물리 부품을 교체해야 하지만, 소프트웨어는 코드 수정으로 문제를 해결할 수 있다. 패치, 핫픽스, 마이너·메이저 업데이트가 계속 이어지는 이유다.
Lehman의 법칙은 프로그램이 진화하지 않으면 죽은 것과 같다는 관점을 제시한다. 출시가 끝이 아니라는 뜻이며, 변경이 가능한 특성은 코드베이스 관리가 무너지면 오히려 위험이 된다. 구조가 흐트러진 코드에서는 작은 수정도 예상하지 못한 부작용을 만들 수 있다.
확장 가능한 아키텍처, 모듈화, 테스트 자동화는 변경 가능성을 실제 운영 가능한 능력으로 바꾸는 장치다.
환경과 요구 변화에 적응하는 방식
순응성은 새로운 요구사항, 운영 환경, 기술 스택의 변화에 대응할 수 있는 성질이다. 하나의 애플리케이션을 Windows, macOS, Linux에서 실행하도록 설계할 수 있고, 사용자 요구나 비즈니스 변화에 맞춰 기능을 바꿀 수도 있다.
이 특성은 변화에 빠르게 대응하는 반복적 개발 프로세스가 필요한 배경이 된다. 모놀리식 아키텍처에서 마이크로서비스로, 온프레미스에서 클라우드로 옮기는 기술 마이그레이션도 순응성의 범위 안에 있다.
느슨한 결합(Loose Coupling)과 높은 응집도(High Cohesion)는 이런 변화에 대비하는 설계 원칙이다. 의존성 주입(DI), 인터페이스 기반 프로그래밍, 설정 중심 설계(Configuration over Convention)가 함께 사용된다.
보이지 않는 산출물을 품질로 관리하기
소프트웨어는 만질 수 없는 논리적 대상이다. 하드웨어처럼 크기·무게·성능으로 바로 평가하기 어렵고, 코드 품질, 유지보수성, 확장성처럼 정성적 판단이 필요한 속성이 많다.
이 때문에 품질을 눈으로 확인하기보다 테스트, 코드 리뷰, 정적 분석 도구를 통해 관리한다. 사용자마다 품질과 가치에 대한 인식도 다를 수 있으므로 사용자 경험(UX)과 인터페이스 설계도 중요해진다.
UML 다이어그램, 아키텍처 다이어그램, API 문서, 사용자 매뉴얼은 무형의 산출물을 공유 가능한 형태로 드러내는 수단이다.
복제는 쉽지만 배포와 통제를 남긴다
소프트웨어는 원본과 동일한 복사본을 무제한으로 만들 수 있으며, 복제 비용은 거의 들지 않는다. 한 번 개발한 소프트웨어를 전 세계에 배포하는 비용은 초기 개발 비용에 비해 미미하고, 이것이 SaaS(Software as a Service) 비즈니스 모델의 기반이 된다.
복사본은 원본과 100% 동일하게 동작하므로 하드웨어 제조에서 생기는 품질 편차가 없다. 인터넷 배포와 CI/CD 파이프라인을 통한 자동화된 배포도 이 특성 위에서 가능해졌다.
반면 복제성은 라이선스와 보안의 관리 과제를 남긴다. DRM(Digital Rights Management), 라이선스 키 관리, 소프트웨어 임치(Escrow) 같은 메커니즘이 필요한 이유다.
내부 구조가 감춰진 시스템을 관측하기
사용자는 인터페이스를 통해 기능을 사용하며 내부 로직을 알 필요가 없다. 이는 캡슐화(Encapsulation)와 정보 은닉(Information Hiding)의 원칙과 맞닿아 있다. 그러나 실행 과정과 내부 구조가 직접 보이지 않는다는 점은 운영과 디버깅을 어렵게 한다.
오류 원인을 찾으려면 로깅, 모니터링, 디버깅 도구가 필요하다. 분산 시스템에서는 트레이싱과 관측 가능성(Observability)의 비중이 더 커진다. 겉으로 단순해 보이는 기능도 내부적으로 복잡한 로직을 가질 수 있으며, 그 차이는 유지보수성을 떨어뜨릴 수 있다.
로그 수집, 메트릭스 모니터링, 분산 추적(Distributed Tracing)은 비가시성을 다루기 위한 관측 가능성 체계의 구성 요소다.
상호작용과 상태가 만드는 복잡성
소프트웨어는 많은 컴포넌트, 상태 변화, 예외 상황이 서로 얽힌 시스템이다. 현대 소프트웨어는 수백만 줄의 코드와 수천 개의 모듈로 구성되며, 단순한 계산기 앱조차 예상보다 복잡한 내부 구조를 가질 수 있다.
컴포넌트 간 관계는 비선형적이어서 작은 변경이 전파되고 예상치 못한 영향을 만들 수 있다. 상태 전이 조합은 지수적으로 늘어나며, 이것이 테스트를 어렵게 만드는 이유가 된다.
복잡성을 제어하려면 모듈화, 추상화, 관심사의 분리(Separation of Concerns), 디자인 패턴 적용이 필요하다.
닳지 않는 소프트웨어와 누적되는 부채
소프트웨어는 물리적으로 마모되거나 노후화하지 않는다. 적절한 저장 매체에 보관하면 무한히 존재할 수 있으며, 30년 된 레거시 시스템이 여전히 동작하는 사례도 많다. 온도, 습도, 진동 같은 물리 환경의 영향을 받지 않고 반복 사용만으로 성능이 저하되지는 않는다.
다만 데이터 누적이나 리소스 누수로 인한 성능 저하는 발생할 수 있다. 비마모성은 소프트웨어를 오래 남게 하지만, 기술 부채(Technical Debt)와 레거시 시스템 문제도 함께 축적한다. 지속적인 리팩토링과 현대화가 없으면 유지보수 비용은 기하급수적으로 증가한다.
특성이 개발 방식으로 이어지는 경로
변경성과 순응성은 폭포수 모델보다 변화에 대응하는 애자일 방법론의 필요성을 뒷받침한다. 무형성, 비가시성, 복잡성은 자동화된 테스트 스위트 없이는 품질을 보장하기 어렵다는 점을 보여 준다.
비가시성을 다루기 위한 로깅, 메트릭스, 트레이싱은 현대 소프트웨어 개발의 관측 가능성 기반이 된다. 비마모성으로 축적되는 레거시에는 지속적인 리팩토링과 기술 부채 상환이 필요하다. 소프트웨어의 강점인 변경성과 순응성을 활용하면서 복잡성을 통제하는 일이 소프트웨어 엔지니어링의 핵심 과제다.
Sources
- "Software Engineering" by Ian Sommerville, 10th Edition
- "The Mythical Man-Month" by Frederick P. Brooks Jr.
- SWEBOK v3.0 - Software Engineering Body of Knowledge
- "Fundamentals of Software Engineering" by Carlo Ghezzi et al.