티스토리 뷰

IT

Software Design

래빗조아 2025. 1. 7. 16:27

1. 설계 해 보신적 있나요?

소프트웨어 개발에서 “설계(Design)”를 해보지 않은 사람은 아마 거의 없을 것입니다. 다만, 설계를 대하는 방식이나 수준은 프로젝트 상황, 조직 문화, 개인 역량 및 경험에 따라 매우 다릅니다. 예를 들어,

  • 초기 단계에서 하는 대략적인 아키텍처 설계
    예) 시스템 전반의 구성, 데이터의 흐름, 각 컴포넌트(모듈) 간 의존 관계, 네트워크 구조, DB 구조 등을 포괄적으로 잡아두는 것.
  • 기능 단위 혹은 화면 단위로 상세히 하는 설계
    예) 특정 기능별로 어떤 함수를 호출하고, 화면(UI)에서는 어떤 컴포넌트를 어떻게 배치하고, 사용자가 어떤 동작(Use Case)을 할 때 어떤 프로세스가 동작하는지 정의하는 것.
  • 문서화 수준의 설계
    예) 요구사항정의서, 흐름도, UML 다이어그램(클래스 다이어그램, 시퀀스 다이어그램, 액티비티 다이어그램), 화면설계서 등을 작성하는 것.

프로젝트 과정에서 요구사항 정의서나 화면 설계서 등이 있으면, 많은 경우 설계 산출물을 만들어내는 경험을 하게 됩니다. 또한 실제 코드를 작성하지 않더라도, 팀 내에서 “이 기능을 어떻게 구현하지?”라는 논의만 해도 이미 일종의 설계를 하고 있는 것입니다.

즉, “코드를 작성하기 위해 머릿속에서 또는 문서화 작업으로 로직을 구상하는 모든 행위가 넓은 의미의 설계”라고 볼 수 있습니다. 그러므로 소프트웨어 개발을 어느 정도 경험했다면, 공식/비공식적으로 설계를 해본 경험이 있을 것입니다.


2. 아키텍처(Architecture)는 무엇인가요?

소프트웨어 아키텍처는 보통 “시스템을 구성하는 요소들(컴포넌트)과 그 요소들 간의 관계(상호 작용), 그리고 이를 둘러싼 환경과의 관계를 전체적으로 조망한 것”을 의미합니다. 조금 더 구체적으로는 다음과 같은 요소가 포함됩니다.

  1. 시스템의 주요 구성 요소
    • 예: 프론트엔드(웹/모바일) 모듈, 백엔드 서비스, 데이터베이스, 외부 연동 API 등
  2. 컴포넌트 간 통신 구조
    • 예: REST API, 메시지 큐, RPC, 데이터 파이프라인 등
  3. 비기능적 요구사항을 충족하기 위한 구조
    • 예: 확장성(Scalability), 보안(Security), 고가용성(High Availability), 장애 대응성(Fault Tolerance) 등
  4. 개발 및 운영 환경
    • 예: 배포 파이프라인(CI/CD), 로그/모니터링 체계, 인프라(클라우드, 온프레미스) 구조 등

아키텍처 설계는 프로젝트 초기에 방향성을 잡는 데 크게 기여합니다. 시스템 규모나 특성, 요구사항(기능·비기능 요구사항 포함)을 고려해 “전체가 어떻게 굴러가야 하는가?”를 결정하는 것이 아키텍처의 핵심 역할입니다.

  • 계획적 설계 vs. 진화적 설계(Evolutionary Design)
    마틴 파울러(Martin Fowler)가 언급하듯이, 초기에 미리 충분히 계획해두는 아키텍처 설계(Plan-driven, Big Up-Front Design)와, 애자일 환경에서 조금씩 변화를 받아들이며 점진·반복적으로 발전시키는 아키텍처 설계가 있습니다.
    조직마다, 프로젝트마다 어느 쪽이 더 적절한지 다르고, 실제로는 두 방식을 적절히 혼합하는 경우가 많습니다.

3. 설계 안 하고 개발할 수 있나요?

결론부터 말씀드리면, 어떤 형태로든 설계는 ‘항상’ 존재합니다. 문서를 쓰지 않더라도, 머릿속에서든 화이트보드에서든, 혹은 회의 테이블 위에 간단하게 스케치하더라도요.

다만, 질문에서 말하는 “설계를 안 하고”라는 것이 “공식적인 설계 문서를 일절 작성하지 않는다”라는 의미라면, 실제로 가능하긴 합니다. 특히 내부 사내 제품을 빠르게 만들어야 하는 스타트업 환경이나, 애자일·XP(Extreme Programming)에서 시도하는 “코드 자체가 산출물이자 설계”인 형태를 예로 들 수 있습니다.

  • 애자일(Agile)에서의 설계
    • 스크럼(Scrum)이나 XP에서는 자칫 “설계 문서 없이 바로 코딩부터 들어간다”라고 오해할 수 있지만, 사실 “짧은 주기로 반복하며 필요할 때마다 ‘가장 적절한 수준’의 설계를 한다”라는 쪽에 가깝습니다.
    • 완벽한 설계를 문서화하고 나서 구현으로 넘어가는 ‘워터폴(Waterfall)’ 방식과 달리, 예측할 수 없는 요구사항 변경, 기술 변화 등을 수용하기 위해 반복적으로 설계-구현-테스트-피드백 사이클을 돌리는 것이 특징입니다.
  • 설계를 안 했을 때 문제점
    • 팀원 간에 공유가 안 되어 혼선을 빚기 쉽습니다.
    • 변경이 발생했을 때, 변화 영향도를 파악하기 어려울 수 있습니다.
    • 향후 유지보수(리팩터링, 기능 확장 등) 시 어려움이 생길 수 있습니다.

결국, 설계 문서가 얼마나 정교하고 ‘무겁게(heavyweight)’ 혹은 ‘가볍게(lightweight)’ 작성될지는 프로젝트 성격, 개발 문화, 고객(또는 이해관계자)의 요구사항 등에 따라 달라집니다.
그러나 “설계 자체를 전혀 하지 않는 개발”은 현실적으로 거의 없으며, 최소한의 구상(Design Thinking)은 필수입니다.


4. 사실 초년생들은 개발부터 시작하는데 맞는 건가요?

신입 개발자의 경우 대부분 코딩부터 익히는 것이 일반적입니다. 간단하게 그 이유를 나누어 보면:

  1. 언어와 프레임워크, 라이브러리 사용 능력 습득이 우선
    • 실제 코드를 작성해야 언어나 프레임워크 특성을 익힐 수 있고, 문법이나 라이브러리 동작 방식을 체득해야 설계 시 “어떻게 구현하면 좋겠다”라는 감이 생기기 때문입니다.
  2. 설계 감각은 구현 경험을 통해 기른다
    • 초년생은 실제 코드를 작성하고, 디버깅하고, 리팩터링하는 과정을 통해 “왜 이 구조로 설계를 해야 유지보수가 쉽고 버그가 적어지는지”를 체득하게 됩니다.
    • 이 과정을 거쳐야만 ‘설계’라는 개념을 더 실감 나게 이해할 수 있습니다.
  3. 현업에서도 주어진 일을 빨리 해결해야 하는 상황이 많다
    • 특히 스타트업이나 빠른 프로토타이핑이 필요한 환경이라면, 문서를 길게 쓰기보다 일단 동작하는 코드를 만들어서 검증하는 일이 우선입니다.

단, 코딩만 반복해서 한다고 해서 자연스럽게 ‘좋은 설계’ 역량이 쌓이지는 않습니다. 일정 수준 이상이 되면, 코드를 정리하는 원칙(SOLID, 디자인 패턴, 리팩터링, TDD 등)을 학습해야 합니다.

  • TDD(Test-Driven Development)리팩터링을 병행하면, 설계를 유연하게 발전시킬 수 있는 감각이 더 빨리 쌓입니다.
  • 코드 리뷰(Code Review)를 통해 다른 시니어 개발자의 설계 철학을 습득할 수 있습니다.

그러므로 초년생이 “처음부터 완벽한 설계 문서를 작성하는 일”보다는, “프로그래밍 기초 실력을 키우면서 설계적 사고도 함께 배워가는 것”이 보다 자연스러운 접근입니다.


5. 추가로 짚어보면 좋은 포인트

  1. 설계와 문서화의 중요성
    • 요구사항 정의서, 화면 설계서, 흐름 분석 문서 등은 추후 유지보수나 협업 시에 큰 도움이 됩니다.
    • 특히 설계자와 개발자가 분리되어 있거나, 다른 부서(예: 네트워크 보안팀)와 협업해야 할 때는 문서화된 산출물이 매우 중요해집니다.
  2. 설계의 불완전성은 테스트 코드로 보완
    • 초기에 완벽한 설계를 하기란 어렵습니다.
    • 요구사항 변화, 고객 의견, 기술 스펙 변화 등으로 인해 설계는 언제나 뒤집힐 수 있습니다.
    • 이런 불확실성을 테스트 코드(TDD, 자동화 테스트 등)로 보완하면, 큰 변화가 있어도 리팩터링 시 품질을 어느 정도 확보할 수 있습니다.
  3. 애자일 선언(Manifesto)과 반복적·점진적 개발
    • 애자일은 20년도 훨씬 전에 제시된 개념이지만, 오늘날에도 “변화에 유연하게 대응하고, 짧은 주기로 가치를 제공한다”라는 측면에서 여전히 유효합니다.
    • 계획적 설계와 진화적 설계를 혼합하며, 문서는 최소한으로 유지하되 꼭 필요한 것은 업데이트하면서 진행하는 방식이 일반적입니다.
  4. 코드가 곧 설계(Design)라는 관점
    • 개발 프로젝트에서는 최종 산출물(코드)이 곧 ‘살아 있는 문서’이기도 합니다.
    • 하지만 커뮤니케이션이나 품질 보장을 위해 가벼운 설계 문서라도 적절히 생성·유지하는 것이 중요합니다.
    • “설계와 코드를 매번 동기화”하기 어렵다는 문제는 늘 존재하지만, 필요 최소한의 문서를 잘 유지하고, 코드 레벨의 리팩터링 및 주석/테스트를 통해 설계 의도를 남기는 것이 이상적입니다.
  5. 분할과 반복
    • 업무를 최대한 작게 분할해야 핵심 결정사항이 보이고, 리스크도 빨리 발견할 수 있습니다.
    • 애자일 스프린트와 같은 짧은 반복 주기로 진행하면서, 그때그때 필요한 수준의 설계(와 문서)를 작성하는 것이 효율적입니다.

6. 결론

  • 설계는 반드시 필요한가?
    • 넓은 의미에서 “개발을 하기 위해 로직을 구상하는 모든 과정”이 이미 설계이므로, 무조건 필요합니다.
    • 다만, 문서화를 어느 정도 깊이·방식으로 가져갈지는 조직이나 프로젝트 환경에 따라 크게 달라질 수 있습니다.
  • 아키텍처란 무엇인가?
    • 시스템 전반의 큰 그림(구성 요소, 상호 작용, 기술 스택, 운영 환경 등)을 정의하여, 요구사항(기능·비기능)을 어떻게 만족시킬지를 설계하는 것입니다.
  • 설계 없이 코드를 짤 수 있는가?
    • 공식적 설계 문서 없이 진행하는 “가벼운 설계” 형태라면 가능하지만, 아예 아무런 설계도 없이 코딩하는 것은 팀 프로젝트 규모가 커질수록 위험도가 크게 올라갑니다.
  • 초년생들이 코딩부터 시작하는 게 맞는가?
    • 일반적으로는 맞습니다. 실제 구현 경험을 통해 언어와 프레임워크의 특징을 습득해야 설계 역량도 함께 성장합니다.
    • 다만, 어느 시점부터는 코드 설계 원칙(SOLID, 패턴, 리팩터링 기법, TDD 등)을 병행해서 학습해 나가는 것이 더 바람직합니다.

결국 "설계와 개발은 별개가 아니라 서로 긴밀하게 연결된 활동”이라는 점이 핵심입니다. 설계를 통해 명확하게 방향과 구조를 잡고, 개발을 통해 실제로 구현하며, 필요한 경우 테스트 코드나 문서를 통해 변화와 품질을 관리해 나가는 과정이 이상적인 형태일 것입니다.

댓글