본 글은 인공위성과 관련된 시스템을 개발하는 업무 중 좋은 설계란을 고민하며 작성한 글입니다.

현재는 다른 도메인으로 이직을 한 상태이지만 작성 시 일반적인 프로그래머의 입장에서 작성하였기 때문에 다른 분야의 프로그래머도 함께 고민할 수 있는 주제라고 생각합니다.


좋은 설계를 고민해보면 일단 설계가 무엇인지 정의가 필요합니다. SW공학에 영향을 많이 준 건축의 설계 정의는 다음과 같습니다.

건축설계의 정의(建築設計, architectural design)는 건축물을 구축하기 위하여 요구되는 기능과 형태와 구조를 결정하고 물리적 형식을 구체화하는 과정을 총칭한다. 따라서 건축계획을 조정하고 배열하고 구조화하여 도면을 통해 실질적으로 건축물을 구상하는 과정을 의미한다.

[네이버 지식백과] 건축설계 Architectural Design

위의 정의를 따르면 설계는 다음 결과물을 생성합니다.

  • 요구 기능
  • 형태, 구조
  • 도면

건축은 위의 설계에 따라 제조를 하여 실질적인 건축물을 만듭니다.

이 영향을 받은 SW 공학은 설계 단계에서 설계서를 작성하고 제조 단계에서 코드(구현)을 한다고 자연스럽게 인식되었습니다. 대표적인 설계서는 다음과 같습니다.

  • 요구사항 정의서
  • 기본 설계서 (기능, 자료 등)
  • 상세 설계서

하지만 여기에서 중요한 것은 SW에서 설계는 설계서가 끝이 아니라는 점입니다. 고객의 불명확한 요구사항, 고객-개발자 간의 용어 차이 등으로 인해 실제 소프트웨어 제품을 사용할 때까지 고객은 아무런 응답이 없다가 제품을 받는 순간 엄청난 수정사항을 요청하게 됩니다.

그리고 코딩을 완료한 후에 적는 설계서가 가장 정확합니다. 더 좋은 구현을 위해 설계의 유연한 변경이 가능합니다. 그렇다고 무턱대고 근간을 바꾸는 것이 아닌 철학과 기준이 명확한 리팩토링은 건축에서 볼 수 없는 모습입니다. 글쓰는 프로그래머 :: 소프트웨어 설계가 완벽할 수 없는 다섯 가지 이유에서도 소프트웨어 설계의 특성이 기존 공학과는 다르다고 설명합니다.

즉, 소프트웨어 설계는 변경이 유연하며 요구사항에 따라 지속적으로 발전해나간다는 큰 특성을 가집니다.

일반적인 좋은 설계 요소

그럼 먼저 좋은 설계라고 공통적으로 말하는 요소는 다음과 같습니다.

  • 추상화
  • 유연성

책, 학교에서 항상 언급되는 추상화를 통해 확장성과 변경이 용이한 구조를 가진다. 이런 말이 많이 나옵니다. 저의 생각에는 추상화의 가장 큰 효과는 ‘도메인 문제에 대한 요구사항을 명시화’를 한다는 점입니다. 추상화를 통해 구현체를 분리함으로써 유연성을 가지고 궁극적으로는 도메인 문제를 벗어나지 않게 잡아주는 방향이라고 생각합니다. 그리고 추상화를 통해서 유연성도 제공합니다. 도메인 문제의 해결은 유지하며 기술적 해법을 다양하게 가져갈 수 있습니다.

좋은 설계를 통해 우리는 다음과 같은 효과를 얻을 수 있습니다. 모든 효과는 요구사항이라는 도메인 문제 해결을 위해 가장 필요한 요소들입니다.

즉, 좋은 설계의 목적이 다음과 같습니다.

  • 명시적인 도메인 요구사항의 표현
  • 요구사항을 만족하며 개발 중 변경용이성 및 확장성

우리가 만드는 시스템

인공위성

이미지 참고1 쎄트렉아이 홈페이지

위성에 대한 개발도 하지만 외주를 받는 경우에는 고객으로부터 전달된 요구사항을 구현하여 시스템을 만들어야 합니다. 이런 경우일수록 특히 더 좋은 설계에 대한 고민이 필요합니다.

인공위성 관련 프로젝트는 다음과 같은 특성을 가집니다. 일반적인 제조업인 경우 유사한 부분도 있고 운영 기간은 특이하게 매우 길다는 특징이 있습니다.

  • 인공위성 분야에 대한 높은 이해도 및 학습능력
  • H/W 제약으로 인해 명확한 요구사항
  • 기획 & 사업에 대한 높은 이해도가 필요
  • 안정성 확인을 위한 긴 시험 기간
  • 오랜 운영 기간 10년 이상

어떻게 좋은 설계와 구현을 할 것인가?

일반적인 방법은 “1. 테스트 주도 개발”, “2. 도메인 주도 개발” 과 같은 개념을 활용한 설계/개발 방법입니다. 인공위성, 제조업의 경우 H/W에 대한 의존성이 상당히 높습니다. 즉 스펙이 정해진다면 ‘공식(수식, 알고리즘 등)‘과 ‘시나리오(자세 제어 관리, 영상 촬영 시나리오 계획 등)‘을 구분하여 접근합니다.

‘공식’의 경우 탄탄한 테스트를 기반으로 정해진 원칙대로 구현하여 검증하면 됩니다. 특히 이 때 TDD(Test Driven Development)는 정말 효과적입니다. 알고리즘 혹은 수식의 검증 값은 제조사(위성 카메라 혹은 제어 시스템)에서 전달되기 때문에 TDD를 연습하며 구현하기에 적합합니다. 테스트를 통해 구현된 로직의 안정성을 항상 검증할 수 있습니다. 하지만 전체 인공위성 시스템을 고민하였을 때 ‘공식’은 너무나 작은 영역입니다.

‘시나리오’는 일반적인 소프트웨어 개발 환경과 유사합니다. 그래서 이를 좋게 만들기 위해서 더 많은 고민이 필요합니다. 특히 인공위성의 경우 온보드/지상시스템 모두 정확한 시나리오가 명세화 되고 구현을 시작합니다. 그리고 다른 분야와 다르게 변화 가능성이 적은 산업입니다.

방법 1. 시나리오를 테스트 하기 좋은 설계

테스트하기 좋은 설계란 첫 번째로 의존성이 적은 설계입니다. 인공위성 시스템은 대부분 명확하게 서브시스템으로 구분하여 역할이 분리되어 있습니다. 그런 특정 서브시스템 내에서 하는 기능 위주로 시나리오를 시험할 수 있는 테스트 코드를 먼저 짠다면 ‘도메인 문제에 대한 요구사항’을 벗어나지 않고 집중하여 문제를 해결할 수 있습니다.

특히 인공위성 시스템에서 시나리오를 테스트하는 코드를 먼저 짜는 일이 중요한 것은 상대적으로 일반 IT회사에 비해 적은 수의 프로그래머가 시스템 개발에 참여합니다. 개발에 필요한 시간은 한없이 부족하기 때문에 명확하게 자신이 풀어야 하는 문제를 명시화하여 작업을 하는 것이 중요합니다. 이는 TDD보다는 BDD(Behavior Driven Development)와 유사한 접근입니다. BDD 적인 접근이 매우 용이한 이유가 인공위성 시스템의 경우 제약사항이 많기 때문에 시나리오 변경이 쉽지 않습니다. 즉 초기에 작업한 시나리오 테스트 코드를 오랜 시간 활용 가능하고 장기간 수행하는 인터페이스, 통합, IOT와 같은 기간에도 유용하게 활용 가능합니다.

만약 어떤 코드를 수정했더니 전혀 예상하지 못 했던 곳에서 버그가 발생한다면 두 시나리오는 의존성이 있는 상태로 도메인적으로 분리를 해야할 지 혹은 공통 요소를 어떻게 추출해야할지 고민할 수 있는 좋은 방법입니다.

물론 의존성 없는 코드를 작성할 수는 없습니다. 하지만 의존성을 최소화하는데 테스트를 먼저 작성하는 것이 큰 도움이 된다고 생각합니다. 테스트 코드의 Arrange 부분이 복잡하다면 자연스럽게 의존성을 줄여야겠다는 생각이 듭니다.

  • 시나리오/테스트 주도를 통해 최소한의 코드 작성
  • TDD, BDD를 이용한 테스트하기 좋은 설계

방법 2. 적정 설계

적정기술(適正技術, appropriate technology)이란 그 기술이 사용되는 사회 공동체의 정치적, 문화적, 환경적 조건을 고려해 해당 지역에서 지속적인 생산과 소비가 가능하도록 만들어진 기술로, 인간의 삶의 질을 궁극적으로 향상시키는 기술을 말합니다.

설계의 분야에서도 동일하게 적용된다고 생각합니다. 바로 “적정 설계”가 필요합니다.

회사의 프로젝트 비용(개발 아웃소싱의 경우) 및 근무시간, 개발자의 역량을 고려해서 설계 수준이 결정이 필요합니다. 당연히 한없이 아름다운 프로젝트를 만들면 좋겠지만 그 정도에 대한 것은 합의가 필요합니다. 좋은 설계를 하기 위해서 무작정 프로젝트 마일스톤을 무시할 수는 없습니다. 특히 스타트업은 마켓이 오픈되는 마일스톤이 매우 중요합니다. 이와 유사하게 제조업의 한 종류인 인공위성의 경우에도 H/W와의 통합시험와 같은 일정이 매우 중요합니다.

결국 적절한 지점을 찾아야합니다. 그리고 그 일을 할 수 있는 것이 PM(Project Manager) 혹은 PL(Project Leader)의 업무라고 생각됩니다. 업무의 조율 및 할당을 통해서 현재 가진 자원으로 최대의 효율을 내는 것이 중요합니다. 결국 이러한 효율은 프로젝트 구성원의 능력으로부터 오는 것이기 때문에 ‘좋은 실력’을 가진 구성원 혹은 ‘좋은 가이드’를 가진 회사가 필요하다고 생각합니다.

위와 같이 말했지만 프로그래머로의 입장은 항상 충분한 일정을 요구하며 최고의 품질을 뽑아내는데 열정을 사용해야된다고 생각합니다. PM은 조율을 하지만 프로그래머는 최고를 향해서 항상 집중하는 환경이 필요합니다.

좋은 설계 능력을 키우자, 좋은 인재가 되자

프로그래멍

이미지 참고2 Photo by BadBoy from Pexels

테스트 하기 좋은 설계의 경우에는 TDD 방향의 접근이 시야를 넓힐 수 있는 좋은 기회를 제공합니다. 하지만 TDD를 한다고 테스트하기 좋은 설계가 되지 않습니다. 기존적인 패턴 혹은 도메인 문제의 해결을 어떻게 심사숙고했냐에 따라 그 산출물의 퀄리티 차이 큰 것이라고 예상됩니다.

적정 설계라는 것은 이미 제한된 조건(비용, 인력, 기간)으로 결정되어 버리는 요소입니다. 제한된 자원 내에서 가장 좋은 품질을 위해서 적정 설계 활용하는 것입니다. 그러기 위해서는 뛰어난 인재가 필요합니다.

사실 뛰어난 능력은 좋은 프로그래머가 있다면, 그리고 그 프로그래머가 정말 좋은 인재라면 자연스러운 멘토링과 분위기 전파로 프로젝트 구성원에게 긍정적인 효과를 줄 것이라고 생각합니다. 특히 SW 분야에서 실력은 보이지 않기 때문에 평가하기 어렵지만 멘토링 및 영향력을 어마어마 합니다.

이러한 분이 주변에 있다면 행운이며 좋은 회사에 다니고 있다고 생각하며 실력을 키우고 없다면, 채용을 건의하면서 자신이 그런 사람이 될 수 있도록 많은 학습이 필요하다고 생각됩니다.


결국 장인정신이 필요한 것 같습니다.

자신의 가치, 역량을 키우기 위해서 스스로 노력(장인들의 조언, 책, 아티클을 깊게 이해)하고 투자한다면 자신이 희망하는 업무, 기술을 주도적으로 이끌고 갈 수 있다고 생각합니다. 즉, 이렇게 회사를 자신의 역량으로 이끌 수 있는 사람이 좋은 인재이고 프로그래머로서 좋은 인재인 조건 중 하나인 설계 능력을 키우는 방법으로는 훌륭한 저서, TDD, DDD의 학습과 실천(실천이 가장 중요합니다)이 역량을 키우는 가장 효과적인 방법이라고 추천하고 싶습니다.

저도 오늘도 어제의 저보다는 더 나은 상태가 되길 위해 투자하고 있습니다. :)


  1. 이미지 참고[1] 쎄트렉아이 홈페이지 | https://www.satreci.com/ [return]
  2. 이미지 참고[2] Photo by BadBoy from Pexels [return]