2020년 3월 29일 일요일

[Software Spec Series 9] 여러 종류의 스펙 문서 유형

소프트웨어는 하루짜리부터 몇 년짜리 대형 프로젝트도 있다. 이런 모든 프로젝트에 동일한 스펙 문서를 적용하면 비효율적이다. 스펙 문서의 형태는 매우 다양하며 상황에 맞는 문서를 적절히 사용하는 것이 좋다.

이슈관리시스템의 한 줄 또는 몇 줄의 설명


스펙이라고 하면 수십에서 수백페이지의 문서를 먼저 떠올리지만 상황에 따라서는 Jira나 Redmine과 같은 이슈관리시스템의 이슈 하나, 또는 한 줄이 스펙이 될 수도 있다. 보통 작은 유지보수를 위한 변경에서 주로 적용되지만 무엇을 개발해야 하는지 명확하게 정의가 된 것이라면 한 줄 또는 몇 줄의 글이라도 훌륭한 스펙이 될 수 있다.


엔지니어링 One-pager


SRS 등의 제법 큰 템플릿을 가진 문서에 정식으로 스펙을 작성하기에는 프로젝트의 규모가 작거나 이슈가 별로 없을 경우에 작성을 한다. 이슈관리시스템에 간단히 이슈를 정리하고 진행하기도 하지만 굳이 엔지니어링 One-pager라는 문서를 작성하는 이유는 스펙을 작성하는 정식 절차를 밟기 위함이다. One-pager라도 스펙을 일단 작성하면 공식 리뷰를 거쳐서 여러 사람의 의견이나 도움을 공식적으로 받을 수 있다. 그러면 개발하려고 하는 방향이 맞는지 이미 다른 팀에서 비슷한 것을 개발하거나 검토해 놓은 것이 있는지 더 좋은 방법은 없는지 의견을 받을 수 있다. 또한 One-pager의 내용은 공식적으로 다른 사람, 다른 팀에게 공유가 되어서 회사내에서 지식 공유에 도움이 된다.

보통 다음과 같은 경우에 엔지니어링 One-pager를 작성한다.


  • 메모리를 50% 절약하는 알고리즘 구현 시도
  • 최신 버전의 Visual Studio로 이식하는 프로젝트
  • 새로운 그래픽 엔진으로 교체를 하는 일주일짜리 프로젝트


수십페이지의 SRS


가장 일반적으로 스펙을 작성하는 방법이다. 비즈니스 전략, 환경, 기능, 비기능, 성능 등 소프트웨어를 개발하면서 고려해야 할 대부분의 내용이 포함되어 있다. 이 책에서는 SRS에 대한 내용을 자세히 다룰 것이다.

수백, 수천페이지의 거대 방법론의 스펙 문서


거대 방법론에서는 문서를 수십개 이상 작성하기도 한다. 이런 방법론에서는 스펙이 하나의 문서로 정리되는 것이 아니고 여러 개의 문서에 분산되어서 작성된다. 장점으로는 프로젝트에 투입된 역할별로 필요한 문서를 정해서 보면 되는 것이다. 단점으로는 중복이 많이 발생하고 하나의 업무를 하기 위해서 매우 많은 문서를 봐야 한다. 또한 한번 작성하고 나면 수정이 매우 어렵다. 아래와 같은 문서들이 그 예다.

  • 요구사항정의서
  • 업무기능분해도
  • 업무흐름도
  • 액터카달로그
  • 유스케이스 다이어그램
  • 논리 ERD
  • 도메인 엔티티 정의서
  • 분석패키지 다이어그램
  • 코드정의서
  • 인터페이스 정의서
  • 컴포넌트 명세서
  • 화면 정의서
  • 메뉴 구조도

기타


  • 테스트 코드로 스펙 작성하기
  • 소스코드로 스펙 작성하기
  • 유저 스토리
share abctech.software

2020년 3월 15일 일요일

[Software Spec Series 8] 어떻게 소프트웨어를 빠르게 개발하는가?


소프트웨어는 빠르게 개발하는 것이 매우 중요하다. 소프트웨어 개발 기간이 오래 걸린다면 적절한 시장 진입 시기를 놓칠 수 있다. 소프트웨어 시장 변화는 매우 빨라서 너무 오래 개발을 하면 그동안 시장의 상황이 바뀐다. 경쟁자들은 새로운 제품을 출시하여 우리 회사에서 지금 개발하고 있는 제품이 뒤쳐지곤 한다. 또한 오랜 프로젝트는 개발자와 프로젝트 참여 인원들을 지치게 만든다. 이런 현상이 프로젝트를 더욱 더디게 한다. 프로젝트가 기간이 길어지면 그동안 새로운 요구사항이 추가될 가능성이 높다. 기획자는 변화하는 시장의 상황을 무시할 수가 없기 때문이다. 그래서 프로젝트는 더욱 늘어지고 품질은 떨어진다.

최근의 대부분의 개발 방법론들은 소프트웨어를 빠르게 개발하는 것을 중요시하고 있으며 회사에서도 소프트웨어를 빠르게 개발하기 위한 많은 노력을 들이고 있다. 그럼 어떻게 해야 소프트웨어를 빠르게 개발할 수 있을까? 소프트웨어를 빠르게 개발하기 위해서 고려해야 할 것은 매우 많지만, 여기서는 스펙 관점으로 살펴보려고 한다.

(느린 순차적 개발)


빌딩을 쌓을 때는 1층을 쌓고 2층을 쌓아야 한다. 1층을 쌓기 전에 2층을 쌓는 것은 불가능하다. 조립식 빌딩이라면 얘기가 다르지만 대부분의 빌딩은 순차적으로 쌓아 나간다. 소프트웨어도 이런 방식으로 순차적으로 개발을 해야 한다면 매우 오랜 시간이 걸릴 것이다. 거대한 소프트웨어는 수십년이 걸릴 수도 있다.

하지만 소프트웨어는 빌딩과 같이 1층이 완성되기를 기다렸다가 2층을 만들 필요가 없다. 1층과 2층의 인터페이스만 잘 정하면 따로 만들어서 합치면 된다. 다 만들어서 나중에 합치는 방법도 있지만, 1층과 2층의 뼈대만 만들어 놓고 동시에 만드는 방법을 더 많이 사용한다. 나중에 합치게 되면 합치는 과정에서 문제가 발생하기도 하지만, 처음부터 합쳐 놓고 동시에 만들면 합치는 과정에서 생기는 문제가 줄어든다.


(빠른 병행 개발 - 개발 후 통합)


(빠른 병행 개발 - 통합 후 개발)


이렇게 소프트웨어를 동시에 개발하여 프로젝트 기간을 단축하려면 분석, 설계가 잘 되어 있어야 한다. 특히 컴포넌트를 잘 나누고 인터페이스를 견고하게 정의해야 한다. 인터페이스는 간결하게 정의를 해야 각 모듈 간의 연동이 쉬워진다. 인터페이스는 확고하게 정의를 해야 하며 나중에 함부로 바꾸면 안된다. 물론 한번 정의한 인터페이스가 프로젝트 종료 시까지 변경되지 않으면 가장 좋겠지만 쉬운 일이 아니다. 개발 도중에 인터페이스를 변경하면 처음에 잘 정의한 경우보다 수십배의 변경 비용이 들어간다. 따라서 분석, 설계 시 최대한 노력을 하여 인터페이스가 가능하면 변경되지 않도록 정의를 해야 한다.

프로젝트가 크고 참여 인원이 많을수록 순차적인 개발보다 병렬 개발이 훨씬 좋다. 수십명의 개발자가 참여하는 프로젝트에서 순차적인 개발이란 거의 불가능하다. 수십명의 개발자가 처음부터 잘 통합된 소스코드를 기반으로 병렬로 개발을 해야 프로젝트를 빨리 끝낼 수 있다.


(순차개발과 병행개발의 개발 속도 차이 비교)


인터페이스는 상호간의 약속이다. 클라이언트와 서버 모듈을 병렬 개발할 때 인터페이스는 클라이언트 개발팀과 서버 개발팀의 약속이다. 인터페이스를 확정하면 서로 약속을 한 것이고 서로 헤어져서 따로 개발을 해도 문제가 없을 정도로 신뢰를 할 수 있어야 한다.

프로젝트 기간 내내 인터페이스를 잘 유지하기 위해서는 지속적인 통합이 필요하며 유닛 테스트, 테스트 자동화도 유용하다. 개발자는 자신이 작성한 모듈을 완성한 후에 소스코드관리시스템에 등록하는 것이 아니라 좀더 잦은 주기로 등록을 하여 프로젝트 주기 내내 소스코드가 정상적으로 빌드가 되도록 유지해야 한다. 너무 늦게 통합을 할 경우 많은 문제를 발생시키는 “통합의 지옥”을 맛보게 된다.

커밋은 하나의 기능이 완성이 되었을 때, 전체 클래스 또는 전체 컴포넌트를 모두 구현할 때까지 기다릴 필요가 없다. 하지만 항상 빌드는 되어야 한다. 또한 내가 소스코드를 수정하는 동안 다른 곳을 수정한 동료들의 소스코드와 머지(Merge)가 잘 되어서 제대로 빌드가 되는지 확인을 해야 한다. 보통은 적어도 하루에 한두 번 이상 커밋을 한다. 며칠씩 커밋을 하지 않고 지나가지는 않는다.

지속적인 통합을 위해서는 툴을 사용해도 되고, 직접 스크립트를 작성해서 구축을 해도 된다. 지속적인 통합을 도와주는 툴을 CI툴이라고 하며 Jenkins, Bamboo 등이 있다. CI툴 자체가 중요한 것은 아니지만 CI툴은 지속적인 통합을 조금 쉽게 해준다. 중요한 것은 지속적인 통합 활동을 성실히 하는 것이다.

지속적인 통합을 위해서는 주기적인 빌드가 필수다. Build on commit을 하기도 하고 Daily build를 하기도 한다. 밤에 빌드를 한다고 해서 Nightly build라고 하기도 한다. 프로젝트 기간 내내 Daily build는 실패가 없어야 한다. Daily build가 실패하면 인터페이스가 깨졌거나, 어떤 개발자가 깨진 소스코드를 올렸을 수 있다. 빌드가 깨지면 여러 개발자들이 개발에 차질을 빚게 된다. Daily build가 깨진 것을 브로큰 트리(Broken tree)라고 부르며 즉각 해결을 해야 한다.

거대한 시스템일수록 병렬 개발은 꼭 필요하다. 거대한 시스템의 구조를 얼마나 간결하게 하는지가 설계의 중요 요소다. Architect는 복잡한 시스템을 최대한 간결하고 복잡도를 줄여서 시스템의 개발, 유지보수 효율을 높여야 한다. 병렬 개발을 할 때 어려운 점은 내가 필요로 하는 컴포넌트가 아직 구현이 안되어 있어서 기능을 확인할 수 없다는 것이다.

예를 들어보자. 나는 사용자 관리 화면을 개발하고 있고 getUserList()라는 함수가 필요하다. 나는 사용자 목록을 출력하는 화면을 만들고 있는데 getUserList()를 개발하는 개발자는 아직 이 함수를 구현하지 않은 상태다. 그럼 나는 getUserList() 함수가 개발되기 전까지는 내가 만든 사용자 목록 화면을 테스트 해볼 수가 없다. 그럴 때는 getUserList() 함수에 가짜 코드를 추가하면 된다. 실제로는 DB에 쿼리를 해서 사용자 목록을 가져와야 하지만, 가짜로 Hard coding을 해서 사용자 목록을 넘겨주는 것이다. 물론 이런 가짜코드는 필요에 따라서 언제든지 넣고 뺄 수가 있어야 한다.

C언어로 개발을 한다면 다음과 같은 형태가 될 것이다. 아주 간단한 예를 든다.
#define USE_FAKE
RET getUserList(userdata *pData[], int &num)
{
#ifdef USEFAKE
  // make fake data
  num = 2;
  pData[0]->userid = 1;
  pData[0]->username = “John”;
  pData[1]->userid = 2;
  pData[1]->username = “Tom”;
#else
  // get data from database
#endif
  return RET_SUCCESS;
}
(병행 개발을 위한 소스코드 예)

이와 비슷하게 개발 언어에 따라서 적절한 방법으로 병렬 개발하는 아이디어를 적용하면 된다. 병렬 개발을 위와 같이 각자 서로 다른 모듈을 개발하는 경우도 있고 하나의 모듈을 여러 개발자가 개발하는 경우도 있다.

잘 분석, 설계된 소프트웨어는 이와 같은 방법을 사용하여 병렬 개발을 진행하여 소프트웨어를 빨리 개발할 수 있다.

share with abctech.software

2020년 3월 1일 일요일

[Software Spec Series 7] SRS란 무엇인가?

소프트웨어 요구사항을 분석해서 작성하는 스펙 문서의 형태와 종류는 셀 수 없을 만큼 다양하다. 개발방법론에 따라서 제시하는 문서도 다르고 그 개수도 천차만별이다. 이 시리즈의 글에서 소개하고 주로 다룰 문서는 SRS다.

SRS는 Software Requirements Specification(s)의 약자다. Specification 혹은 Spec(스펙)이라고도 한다. SRS는 IEEE830에서 문서를 작성하는 가이드가 정의되어 있고, DoD(미국 국방부) 표준 문서이다.

SRS는 스펙 작성의 원리를 이해하는데 매우 유용하다. 어떠한 형태의 스펙 문서를 작성하더라도 스펙 작성의 원리를 이해하는 것은 매우 중요하다. 스펙을 작성할 때 생각하는 방법, 작성하는 프로세스, 포함되어야 할 내용, 각 내용에 대한 작성 가이드가 모두 포함되어 있다. SRS 역사는 오래 되었지만 스펙을 작성하는 원리는 지금도 변하지 않았다. 앞으로도 크게 변하지 않을 것이다. 그래서 SRS를 작성하는 원리를 깨우친다면 어떠한 방법론 하에서도 스펙을 잘 작성할 수 있을 것이다.

SRS는 IEEE에서 만든 표준 템플릿과 작성 가이드가 있다. 회사마다 조금씩 수정해서 자신의 회사에 맞는 템플릿을 별도로 가지고 있지만, 서로 매우 유사하여 SRS는 전세계 표준이라고 보면 된다. 소프트웨어 회사라면 각자 회사와 개발하는 제품의 특성에 맞게 커스터마이징 해서 사용하는 것이 좋다.

share with abctech.software