처음에 Visual Studio 2017을 한글 윈도우에서 설치하고 나면 메뉴와 각종 에러 메시지들이 한글로 나오게 된다. 하지만 각종 문의를 하거나 에러에 대해서 검색할 때는 영문 에러 메시지가 더 나은 결과를 보여줄 때가 많다. 아래와 같이 언어팩을 추가하고 설정을 변경하면 영문 메뉴와 에러 메시지들이 나오도록 변경할 수 있다.

 

Visual Studio 2017 Installer를 실행하여 언어 팩에서 영어를 추가한다.

 

 

그 다음 Visual Studio 2017을 실행한 뒤 도구 -> 옵션 -> 국가별 설정을 선택한 뒤 언어를 English로 바꿔주고 프로그램을 재 시작하면 영문으로 변경된다. 이제 에러 메시지를 그대로 긁어 검색하면 대개 Stackoverflow 사이트에서 원하는 답변을 첫번째로 얻게 될 것이다.

 

 

 

프로그램은 현실세계의 추상화

고난이도의 알고리즘에 기반한 프로그램이거나 혹은 무수한 쿼리문을 날려 그 결과값을 화면에 뿌리기만 하는 관리 프로그램이라도 그 근본 구조는 다르지 않다. 객체지향 프로그래밍에선 결국 프로그램은 현실세계의 추상화이기 때문이다. 사용자의 요구사항을 추상화된 모델을 만들어 처리하고 응답하는 것이다.

 

회사의 자재관리 프로그램을 짠다고 생각해 보자. MVC 패턴에 입각하면 UI는 단순히 모델의 반영이며, 모델에 값을 전달하는 것에 불과하다. 물론 요즘 프로그램의 UI는 복잡하고 화려해지면서 그 자체가 하나의 프레임웍으로 구현된다.

UI프레임웍은 이미 충분히 일반화 되어 있다 . MFC, WPF, WinForm등 그저 갖다 쓰기만 하면 된다.

하지만 모델은 어떤가. 모든 프로젝트는 결코 동일하지 않듯이 프로그램도 동일한 비지니스 로직을 표현하는 것은 없다. 불가능한 것은 아니나 비지니스 로직을 프레임웍으로 만들기는 대단히 어렵다. 처음부터 비지니스 프레임웍을 구성하도록 하기보다는 프로그램에 맞도록 모델들을 잘 연계한 구조 (아키텍처, 골격)를 가져야 확장성과 유지보수성을 극대화할 수 있다. 

 

  • UI 결합 코드의 일반적인 사례

여러 회사에서 여러 프로그램을 접해보면서 놀라운점은 대부분의 프로그램이 UI에 밀접하게 연계되어 있다는 것이다. UI를 분리할경우 어떠한 작업도 진행할 수 없도록 짜여져 있다. 더욱 놀라운 것은 그게 문제인지조차 모르는 경우가 허다하다. 너무나 많은 프로그래머들이 그런식으로 작성해왔기 때문이다.

 

모델과 뷰의분리가 이해가 가지않는다면 역설적으로모델과 UI결합된 것을 보면된다. 다음 화면은 간단한 곱셈을 연산한 값을 출력하는 프로그램이다.

 

단순한프로그램을 어떻게구현할까? 초보자들은 흔히 다음과 같이 짜곤 한다. 

 

voidCBadCalculatorDlg::OnBnClickedBtnResult()

{

       CStringsLValue, sRValue;

       m_editLValue.GetWindowText(sLValue);

       m_editRValue.GetWindowText(sRValue);

       double rLValue = _tstof(sLValue);

       double rRValue = _tstof(sRValue);

       double rRet = rLValue * rRValue;     

 CStringsRetValue;

       sRetValue.Format(_T("%.4f"), rRet);

       m_editRetValue.SetWindowText(sRetValue);

} 

 

계산버튼 누르는이벤트 안에서값을 입력하는 에디터박스 안의값을 가져와서곱하기를 다시결과 값을에디터 박스에넣어 표현한다. 뭐가 문제일까? UI 있을 모델 객체가 없다. 모델객체가 없다면곱하기 테스트같은 것이불가능 해지고, 또한 다른 프로그램에서 계산기를 재사용하는 것이 어려워진다. 물론 복사신공(?)으로 가능하지만, 그건 객체지향 세계에선 가장 범죄 행위(?)중 하나이다.

 

그럼모델객체를 만들어보자. 혹자는 단순한 곱하기인데 굳이 클래스를 만들 필요가 있느냐고 생각할지 모르겠다.  현재의 상황만 보자면 사실 충분하기도 하다. 하지만 프로그램은 생물과 매우 유사한 진화 과정을 거치게 됨을 생각해야 한다.

 

#pragma once

namespace Indy

{

       class Calculator

       {

       public:

             Calculator(void);

             virtual ~Calculator(void);

             double GetResult() { returnm_rResult; }

             double Multiply(doublelValue, double rValue);

             double Multiply(doubleRValue);

       protected:

             double m_rResult;

       };

};

Calculator 구현

#include "StdAfx.h"

#include "IndyCalculator.h"

using namespace Indy;

Calculator::Calculator(void)

{

       m_rResult = 0;

}

doubleCalculator::Multiply(double lValue, double rValue)

{

       m_rResult =lValue * rValue;

       return m_rResult;

}

doubleCalculator::Multiply(double RValue)

{

       m_rResult *=RValue;

       return m_rResult;

}

 

위의 선언부를보면 개의 값을곱하는 함수가있고, 인자가 하나뿐인 곱하기 함수도 있다. 우리가계산기를 사용할 이전의연산 결과에다시 곱하는경우가 있는데, 인자가 하나뿐이 함수의 구현부를 보면 이전의 결과값을 누적함을 확인할 있다.  곱하기를 수행했는지를 알고 싶다면? 곱하기를 히스토리를 30단계까지 보고 싶다면? 곱하기의 결과를 자리씩 끊어서 “,” 붙여 회계 형으로 만들고 싶다면 어덯게 할까?

이제슬슬 머리가 아파오기시작할 것이다. 만약모델이 없고 UI이런 기능을 추가하려면조금씩 UI 기능양쪽과 서로 연관되면서 복잡도는 더욱더커지게 된다.

 

나는 골격을 프레임워크의 단계라고 본다. 만약 여러분이 유사한 프로그램을 정도 만든다고 하면 여러분이 만든 골격이 차츰 프레임워크로 발전할 것이지만 그렇지 않은 경우에는 골격이 아키텍처 차원의  활용성을 가지기는 매우 어렵다. 그러나 짜인 아키텍처는 품질을 유지하고, 개발의 속도를 높이는 데는 막강한 역할을 담당하게 될 것이다.

 

  • 골격이란 프로그램의 핵심기능이 구현된 중요한 구조(아키텍처) 구현물

프로젝트의 초창기엔주변의 자잘한기능이 아닌핵심 기능에집중해야 한다. 우리는 흔히 개발 공정을 작성할 프로그램의 전체 기능을 순서대로 개발하는 오류를 범하기도 한다.

예를 들어 XML 값을 읽어 들여 연산을 결과를 3차원 그래프 출력하는프로그램을 개발할경우 XML파서기 개발부터 시작하는 식이다. 계산기를 만들경우 계산하는기능에 우선집중해야 한다. 결과를 3차원 그래프 표현하거나 XML 출력하는 기능은 핵심 기능이 아니다. 프로젝트의전체를 관통하는주요 흐름만을최대한 빠른시간 내에구현해야 한다.

전체 개발기간의 3-40% 이내의 기간 내에 골격이 완성 되고, 핵심 기능이 구현되지 못한다면 프로젝트는 실패를 예고하고 있는 것이다. XML파서기를 아무리 만들든 무슨소용이 있겠는가? 계산 성능에서심각한 문제가 후반에 발견된다면 말이다.

바로이러한 문제를 조기에확인하기 위해 골격을구현하고 테스트하는 것은 중요한 작업이다. 이 작업이 마무리되면 프로젝트 중, 후반의 작업은즐거운 살붙이기 작업이 것이다.

 

프로그램이 자꾸 버그가 꼬리를 물때, UI의 작은 변경에도 많은 클래스들을 변경해야 할때 자신의 프로그램을 자세히 들여다 보라. 골격이 있는지, 또 있다면 UI와 완전히 분리되어 있는지 살펴볼 일이다.

 

'Successfull Project > Architecture Design' 카테고리의 다른 글

객체지향 코드 - 캡슐화  (0) 2018.12.28

캡슐화의 정의와  C++에서의 응용

캡슐화란 객체가 가지고 있는 내부의 속성을 외부에서 제어하지 못하도록 하는 것을 의미한다.

완벽한 캡슐화라면 내부의 속성값을 직접적으로 바꾸는 행위는 적절하지 않겠지만, 우리는 보통 Setter를 이용하여 속성을 변경하고 Getter를 이요하여 값을 가져오는 것으로 캡슐화를 유지한다.

문제는 Setter는 만들지 않고 Getter만 생성하고 값을 이용하려고 할때 발생한다. Getter는 값을 가져오는 것이라 캡슐화를 깨지 않아야 하지만 속성 객체를 레퍼런스로 넘겨 받게 되면 Getter이자 Setter가 되어 버린다.

Getter가 가진 이런 문제를 해결하기 위해 C++에서는 반환 시 const 형의 레퍼런스를 반환하여 사용자가 수정할 수 없도록 처리 했다

 

class Group

{

public:

//- 빌트인 타입( int, double ......)

int GetID() { return m_nID; }

void SetID(int nID) { m_nID = nID; }

 

//- 객체 타입

const Item& GetItem() { return m_item; }

protected:

int m_nID;

Item m_item;

};

 

위와 같은 심플 객체 외에 List 와 같은 자료구조가 속성인 경우 Getter/Setter를 만드는 것은 대단히 위험한 일 중의 하나였기때문에 필자같은 경우 만든 사례가 없었으며 그런 자료구조를 통채로 넘겨 받아야 하는 구조라면 구조가 잘못된 것이니 고쳐야지 코딩의 기법으로 해결할 문제는 아니라고 생각한다. 자료구조에 접근하는 것은 자료구조를 가지고 있는 클래스에게 요청하여 하나씩 가져오도록 구혔했다.

 

  • C#에서의 캡슐화 적용 방법에 대한 고민 1 - 단순 객체

c#을 공부하면서 이놈 한테는 const가 없고, 모든 클래스는 레퍼런스로 반환되어 Getter를 만드는 것이 상당히 조심스러웠다. 어설프게 Getter를 만들면 넘겨받은 객체가 뭔짓을 해도 막을 방법이 없게 되고, 자신의 속성임에도 불구하고 제어권이 넘어가 버린다. 따라서 개발을 진행하면서 가급적 Setter/Getter를 만들지 않고 꼭 필요한 경우 Getter는 Clone 객체를 생성해서 반환하는 식으로 구현하였다.

 

public class Test2

{

protected Item _slectedItem;

 

public Item SelectedItem

{

get { return _selectedItem.Clone(); } 

//set { _selectedItem = value; }

}

 

}

 

  • C#에서의 캡슐화 적용 방법에 대한 고민 2 - MVVM 을 위한 콜렉션 객체 반환

C#을 이용한 WPF 프로그래밍 시 MVVM 을 이용하여 UI와 모델을 분리하고 Binding 하는 것은 가장 중요한 개발 패러다임의 하나이다. 필자는 이 매커니즘이야 말로 WPF 의 핵심 개발 아키텍처라고 생각한다. 하지만 이때문에 C++과는 다르게 내부의 콜렉션을 넘겨줄 필요성이 있었다.

콜렉션 객체를 클론하여 넘겨주는 것은 부담이 컸고, 그대로 넘겨 버리면 넘겨 받은 쪽에서 마음대로 객체를 추가해도 막을 수 없게 된다. 콜렉션이 가지고 있는 요소들의 변형은 어찌 되었던 간에 최소한 콜렉션 자체가 가지고 있는 추가 삭제 기능만은 막아야 한다고 생각 했다. 한동안 고민을 지속 하다가 콜렉션을 반환할 때 껍데기인 콜렉션을 배열로 변경해 버리는 방식으로 처리했다.

 

public class Test2

{

protected List<Item> _items = new List<Item>();

 

//- 이렇게 넘겨주면 넘겨받은 쪽에서 Items를 통해 마음껏 객체를 추가할 수 있게 된다.

public List<Item> Items1

{

get { return _items; } 

}

 

//- 이렇게 넘겨주면 넘겨받은쪽에서 루프를 이용해서 사용할 수 있지만 객체를 추가할 수 없게된다.

public Item[] Items2

{

get { return _items.ToArray(); }


}

 

}

 

  • 남아있는 과제

Items2 와 같은 방식으로 변경하면 객체를 추가 삭제 할 수는 없지만 MVVM에 필수적인으로 활용되는 ItemsSource 로 binding 할 수 있게된다. 아직은 완전히 해결된 것은 아니다 콜렉션이 가지고 있는 Item의 변형을 막을 방법은 없기 때문이다. 자 캡슐화를 이정도까지 하면 될까? 대부분의 경우 이정도면 충분하겠지만 item의 변경까지 막을 방법을 생각해 봐야겠다.

물론 보다 디자인적인 접근으로 Setter의 작성은 언제나 최소화해야 할 것이다. 완벽한 설계는 더이상 넣을 것이 없을때가 아니라 뺄것이 없을 때가 아니겠는가.

 

프로젝트를 처음 시작할 때 아무리 시간이 촉박해도 작성해야 하는 문서가 딱 두가지가 있다. 이것은 애자일 지향하던, RUP에 맞추던 어떠한 방법론을 사용하더라도 작성하게 된다. 문서의 양은 많아야 30-50 페이지를 넘지는 않는다. 그것은 Sofeware Requierments Specification(이하 SRS), Software Architecture Document(이하 SAD) 이다. 너무나 시간이 촉박할 경우엔 SAD를 생략하기도 하지만 개발이 끝난 후 포스트모템으로 반드시 SAD를 작성하여 회고해야 한다. 우리를 실패를 통해 배우기 때문이다.

 

오늘은 그 중 첫번째인 SRS에 대해서 이야기 하고자 한다. 특히 SRS 가 중요한 것은 스펙을 정함으로써 이후 모든 개발의 모든 분야 일정 예측, 설계, 구현, 테스트의 기준이 되면서, 개발 진행 상황 파악, 의사소통을 할 수 있기 때문이다. 십여년전에 작성을 처음 시작할때는 적절한 템플릿도 없이 생각 나는대로 주욱 작성하였다가 이미 표준화된 양식이 있음을 안 뒤부터는 템플릿에 따라서 작성하였다. 하지만 기계적으로 작성하면서 문서를 위한 문서가 되는 경우도 있었다. 그러한 멍청한 과정을 거치면서 수십차례의 SRS 문서를 작성하고나니 나름대로의 통찰력을 얻었고 과연 이 템플릿의 각 항목에서 무엇을 말해야 하는가를 깨닫게 되었다. 각 목차에 대해서 그것이 무엇을 의미하는가에 대해 설명하려고 한다.

 

아래 내용중 목차와 이탤릭체 설명은 정보 문화사에서 출판한 "소프트웨어 요구사항 패턴 " 에 나온 것을 인용한 것이다. 그 아래에 내가 가진 생각들과 예문들을 시간 날때마다 추가하도록 하겠다.

SoftwareRequirements Specification

1      소개(Introduction)

1.1     목적(Purpose)

문서에요구사항이 명시되어있는 제품또는 애플리케이션을설명한다. SRS전체 시스템 일부에만관련된 것이라면 부분또는 하위시스템을 설명한다.

1.2     문서규칙(DocumentConvention)

텍스트 스타일, 하이라이트 또는 주석과 같은 모든 표준 또는 표기규칙을 설명한다.

1.3     독자대상과 읽는 방법(Intend Audience and Reading Suggestion)

SRS대상으로 하고있는 다양한독자계층을 나열한다. SRS 나머지 부분과, SRS 조직되어 있는 방법을 설명하고, 각각의 독자 계층에 대해 가장 적합한 읽기 순서를 설명한다.

1.4     프로젝트 범위(Project Scope)

설명되고 있는소프트웨어와 목적에 대해간단하게 설명한다. 소프트웨어를 사용자 또는 기업의 목표, 비즈니스 목표, 전략과연계시킨다. 별도의 비전과 범위 문서를 사용할 있다면 내용을 중복시키지 말고 그것을 참조하게 한다. 진화하는 제품의 특정 버전을 설명하는 SRS 장기적인 전략적 제품 비전의 하위집합으로 자신만의 범위 선언을 가지고 있어야 한다.

1.5     참조(Reference)

SRS 참조하고 있는 모든 문서 또는 다른 리소스를 나열하며, 가능한경우에는 하이퍼링크도포함시킨다. 여기에는 사용자 인터페이스 스타일 가이드, 계약, 표준, 시스템 요구사항 명세, 유스케이스 문서, 인터페이스명세, 운영개념문서, 또는 관련 제품의 SRS 포함된다. 읽는 사람이 제목, 저자, 버전 번호, 날짜, 소스 또는 위치 등의 참조를 이용할 있도록 충분한 정보를 제공한다.

2      전체 설명(Overall Description)

2.1     제품조망(ProductPerspective)

제품의 구성과유래를 설명한다. 제품이 확장되는 제품군의 다음 구성제품인지, 완성된 시스템의 다음 버전인지, 기존애플리케이션을 대체하는것인지, 완전히 새로운 제품인지를 설명한다. SRS 대규모 시스템의 컴포넌트를 정의하는 것이라면, 소프트웨어가 전체시스템과 어떻게연계되는 지를설명하고 간의 주요인터페이스를 설명한다.

2.2     제품기능(ProductFeature)

제품이 가지고있는 주요기능 또는제품이 수행하는중요한 기능을나열한다. 상세한 내용은 SRS 3 절에 설명되어 있기 때문에, 여기에서는 추상적인 요약만 하면 된다. 요구사항의 주요 그룹과 그룹이 연결되어 있는 방법을 설명하는 최상위 데이터 플로우 다이어그램, 유스케이스 다이어그램, 클래스 다이어그램 등이 도움이 된다.

2.3     사용자 계층과 특징(User Classes and Characteristic)

제품을사용할 것으로예상되는 사용자계층을 파악하고그들의 특징을설명한다. 일부 요구사항은 특정 사용자 계층에만 해당될 있기 때문에, 선호하는사용자 계층을파악한다. 사용자 계층은 비전과 범위 문서에 설명되니 관련자들의 하위집합을 의미한다.

2.4     운영환경(OperationEnvironment)

하드웨어 플랫폼, 운영체계와 버전, 사용자, 서버와 데이터베이스의 지리적 위치 등과 같은 소프트웨어가 동작되는 환경을 설명한다. 시스템이아무런 문제없이연동해야 하는다른 소프트웨어컴포넌트 또는애플리케이션을 나열한다. 비전과 범위 문서는 추상적인 수준에서 정보를 포함하고 있을 있다.

2.5     설계 구현 제약사항(Design and Implementation constraint)

개발자가 선택할 있는사항을 제약하는모든 요소와 제약조건의이유를 설명한다. 제약 조건은 다음과 같다.

l  반드시 사용하거나 피해야 하는 특정 기술, , 프로그래밍 언어와 데이터 베이스

l  사용될 브라우저의 유형과 버전과 같이 제품의 운영환경으로 인한 제약

l  필요한 개발 규칙 또는 표준(예를들면 고객의조직이 소프트웨어를유지보수 예정이라면, 조직은 하청업체가 따라야 하는 설계 표기법과 코딩 표준을 명시할 있다.)

l  이전 제품과의 호환성

l  비즈니스 규칙에 따른 제약

l  메모리 또는 프로세스의 제약, 크기, 무게, 비용과 같은 하드웨어의 제약

l  기존 제품을 개선하는 경우에 따라야 하는 기존 사용자 인터페이스 규칙

l  XML 같은 표준 데이터 교환 형식

2.6     사용자 문서(User Documentation)

소프트웨어와 함께제공할 사용자문서를 나열한다. 사용자 문서로는 사용자 매뉴얼, 온라인도움말, 교재 등이 있으며 따라야 하는 문서 전달 형식, 표준 또는 툴이 있다면 그것들을 설명한다.

2.7     가정과 종속관계(Assumptions andDependencies)

가정은 물증또는 확실한지식이 없는경우에 사실이라고믿는 선언으로, 가정이 잘못되거나 이것을 공유하지 않는다면 문제가 발생될 있기 때문에 어떤 가정은 프로젝트 위험으로 간주된다. SRS 읽은 사람은 제품이 특정 사용자 인터페이스 규칙을 따르고 있다고 가정할 있는 반면에, 다른사람은 다른생각을 있다. 개발자는 특정 기능들이 사용자 정의로 작성된다고 가정하지만, 분석가는 이것들이 이전의 프로젝트에서 재사용된다고 믿고 있으며 프로젝트 관리자는 상업용 함수 라이브러리를 구매해야 한다고 생각할 있다.

운영체계의 다음버전 발표또는 산업표준발표와 같이프로젝트가 통제할 없는외부 요소에어느정도 종속되는지를설명한다. 다른 프로젝트가 개발하고 있는 어떤 컴포넌트를 시스템에 통합하려고 한다면, 프로젝트가 해당컴포넌트를 제시간에제공하는 것을기다려야 한다. 이런 종속관계가 프로젝트 계획과 같은 다른 문서에 이미 정리되어 있다면 문서들을 참조하도록 한다.

3      유스케이스(Usecase)

3.1     Usecase 이름

       요약시나리오

       이벤트 흐름

      기본 흐름

      예외흐름

       사전조건

       사후조건

       쟁점

       현실화

4      시스템 특징(System Feature)

4.1     시스템특징 X

3.X 철자확인 같은 단어만으로특징을 설명한다. 각각의 시스템 특징에 대해서는 3.x.1 에서 3.x.3까지의 하위 절을 반복한다.

       설명과 우선순위(Description and Priority)

기능에 대해간단하게 설명하고그것이 높은우선순위인지 낮은우선순위인지를 나타낸다. 우선순위는 프로젝트 중에 변할 있는 동적인 것으로, 요구사항관리 툴을사용한다면 요구사항특성의 우선순위를정의한다.

       자극/응답 순서(Stimulus/Response Sequence)

입력 자극(사용자 행동, 외부 장비의 신호 또는 다른 자극)순서와 기능에 대한동작을 정의하는시스템 반응을나열한다. 자극들은 유스케이스의 초기 대화단계 또는 외부 시스템 이벤트에 해당한다.

       기능요구사항(Functional requirement)

기능과관련된 상세한기능 요구사항을항목으로 나열한다. 이것들은 사용자가 기능의 서비스를 수행하기 위해 또는 유스케이스를 수행하기 위해 사용하는 소프트웨어의 기능들이다. 제품이 예상되는 에러 상황, 무효한입력과 동작에대해 어떻게응답해야 하는지를 설명한다. 각각의 기능 요구사항에 유일한 레이블을 붙인다.

5      외부 인터페이스 요구사항(External InterfaceRequirement)

5.1     사용자 인터페이스

l  시스템이 요구하는 각각의 사용자 인터페이스의 논리적인 특징을 설명한다. 따라야 GUI표준또는 제품스타일 가이드에대한 참조

l  폰트, 아이콘, 버튼 레이블, 이미지, 색상 체계, 필드 순서, 공통으로 사용되는 컨트롤 등에 대한 표준

l  화면 레이아웃 또는 해상도 제약 조건

l  도움말 버튼과 같이 모든 화면에 나타나는 표준 버튼, 기능 또는 탐색 링크

l  단축키

l  메시지 표시 규칙

l  소프트웨어 번역을 원활하게 하는 레이아웃 표준

l  시각장애자를 위한 기능

사용자 인터페이스의설계 상세내용은 SRS 아닌 별도의 사용자 인터페이스 명세에 문서로 정리한다.

5.2     하드웨어 인터페이스(Hardware Interface)

시스템의 소프트웨어와하드웨어 컴포넌트간의 모든인터페이스의 특징을설명한다. 설명에는 지원되는 장비 유형, 소프트웨어와 하드웨어간의 데이터와 컨트롤 연동, 사용될 통신 프로토콜 등이 포함된다.

5.3     소프트웨어 인터페이스(Software Interface)

제품과다른 소프트웨어컴포넌트(데이터베이스, 운영체제, , 라이브러리, 통합 상업용 컴포넌트)간의 연결을설명한다. 소프트웨어 컴포넌트 간에 교환되는 메시지, 데이터와컨트롤 항목을설명한다. 외부 소프트웨어 컴포넌트가 요구하는 서비스와 컴포넌트 간의 통신 성격을 설명하고 소프트웨어 컴포넌트들이 공유할 데이터를 파악한다.

5.4     통신 인터페이스(CommunicationsInterface)

이메일, 브라우저, 네트워크 통신 프로토콜, 전자 문서와 같이 제품이 사용할 모든 통신 기능에 대한 요구사항을 설명한다. 관련된 모든 메시지 형태를 정의하고 통신 보안 도는 암호화 문제, 데이터전송률과 동기화메커니즘을 명시한다.

6      기능 이외의 다른 요구사항(Other Nonfunctional Requirement)

6.1     성능 요구사항(PerformanceRequirement)

다양한 시스템운영에 대한특정 성능요구사항을 설명한다. 개발자들이 적합한 설계를 선택할 있게 만든 논리를 설명한다. 예를 들면 엄격한 데이터 베이스 응답시간 때문에 설계자들은 여러 위치에 데이터베이스를 미러링 하거나 빠른 질의응답을 위해 데이터베이스 테이블의 정규화를 해제시킬 있다. 지원되어야 하는 초당 트랜잭션 , 응당 시간, 연산의정확도와 실시간시스템의 속도조절관계를 명시한다. 또한 메모리와 디스크 공간 요구사항, 동시 사용자 부하 또는 데이터베이스 테이블에 저장되는 최대 row 수를 명시한다.

성능 요구사항은가능한 분명하게계량적으로 표현한다. 예를 들면 “MS XP에서 1GHz P4환경에서 메모리가 60% 여유가 있는 상태에서 데이터 베이스의 질의 95% 3 내에 완료된다 식으로 표현한다.

6.2     안전 요구사항(Safety Requirement)

반드시 방지해야하는 잠재적으로위험한 행동뿐만아니라 반드시취해야 모든 안전장치또는 행동을정의한다. 제품이 따라야 하는 보안인증, 정책 또는 규제를 정의한다.

6.3     보안 요구사항(Security Requirement)

제품에 대한접속과 제품사용에 영향을미치는 보안, 무결성 또는 사생활 문제, 제품이사용하거나 만드는데이터 보호를모두 명시한다. 보안 요구사항은 일반적으로 비즈니스 규칙에서 만들어 지기 때문에, 제품이준수해야 하는모든 보안, 사생활 정책 또는 규제를 모두 명시한다. 이것대신에, 무결성이라고 부르는 품질 특성을 통해 요구사항들을 해결할 있다. 다음은 보안 요구사항의 예들이다.

SE-1 모든사용자는 첫번째로그인 성공한 후에처음에 할당한로그인 암호를즉시 변경해야한다. 초기 암호는 절대로 재사용되지 않는다.

6.4     소프트웨어 품질 특성(Software Quality Attribute)

고객 또는개발자에게 중요한모든 별도의품질 특성을설명한다. 이런 특성들은 명확하고 계량적이며 확인이 가능해야 한다.

7      다른 요구사항(Other Requirement)

SRS다른 부분에서는다루지 않는모든 요구사항을정의한다. 예로 들면 국제화 요구사항, 법적 요구사항 등이 있다. 제품설치, 구성, 시작과종료, 복구와 장애극복, 로깅과 모니터링 운영에 대한 요구사항을 다루는 운영, 관리와 유지보수에 대한 내용을 추가할 있다.

8      부록A: 용어집(Glossary)

9      부록B: 분석모델(AnalysisModel)]

데이터 플로우다이어그램, 클래스 다이어그램, 상태천이도 등과 같은 관련된 분석모델을 설명한다.

10   부록 C : 데이터 사전

11   부록D : 문제 목록(Issues List)

해결되어야 남아있는 요구사항문제들의 동적인 목록이다. 문제들로 TBD, 미결정, 필요한 정보, 해결이 필요한충돌 등으로 표시된항목들이 포함된다. 이것이반드시 SRS일부가 필요는없지만, 일부 기업들은 SRS항상 TBD목록을첨부한다. 문제들을적극적으로 해결해서 품질의 SRS기본 사항을 결정하는 방해가 되지않게 해야 한다.

 

애자일은 보통 12가지 원리로 많이 이야기 되지만 더 기억해야할 프라임디렉티브는 애자일 선언이다.

애자일 선언에서 5가지 가치가 나왔고, 그것이 12가지 원리로 세분화된 것이라고 생각하기 때문이다.

애자일 선언은 아래와 같다.

 

우리는 직접 개발하면서 혹은 남이 개발하는 일을 도와주면서 소프트웨어 개발에 있어서 더 나은 방법을 발견하고 있다. 이 과정을 통해 우리는 다음의 것들을 가치 있게 여기게 되었다.

 

▲‘ 프로세스와 도구’보다는 ‘개인과 상호작용’을

▲‘포괄적인 문서화’보다는 ‘동작하는 소프트웨어’를

▲‘계약 협상’보다는 ‘고객과의 협력’을

▲‘계획을 따르는 것’보다는 ‘변화에 대응’를.

 

이 말은 왼쪽에 있는 것들에도 가치가 있긴 하지만, 우리는 오른쪽에 있는 것들에 더 많은 가치를 둔다는 것이다.”

 

마치 싯귀처럼 운율감마저 느껴지는 이 미려한 선언문은 이후 여러 실천적 방법론-익스트림, 스크럼등 - 의 기준이 되었다.

 

이 선언에 기초하고 이 선언을 따르기 위해 5가지 가치가 이야기된다.

익스트림 프로그래밍 1판에서는 애자일의 가치가 4가지였던 걸로 기억한다.

의사소통, 단순성, 피드백, 용기 여기에 하나가 추가되었다. 바로 '존중' 이다. 

존중에 의해 애자일은 개발을 하는 주체가 상처받기 쉬운 사람이라는 것을 주목하고 있음을 명확히 한다.

즉 4가지 가치는 "존중"에 기반해야 함을 말이다.

 

많은 프로젝트들이 개발에 실패한다. 하지만 어디에도 실패한 프로젝트는 찾아보기 힘들다. 한국적 상황에서 실패란 그 후폭풍이 만만치 않기 때문에 거의 성공으로 결론 내린다. 하지만 성공의 정의가 적절한 예산과 일정, 품질을 만족하는 것이라면 과연 얼마나 우리는 성공했다고 말할 수 있을까?

 

  • 왜 실패 할까?

실패하는 프로젝트는 두가지다. 1) 시간이나 자원이 부족해져서 실패하는 경우와 2) 불가능에 도전한 경우이다. 여기서 두번째는 논외로 하자. 성공할 수 있었지만 실패했었던 경우를 보자.  처절한 죽음의 행진을 한 뒤에야 무엇이 잘못되었는지 알게되면 차후를 위해 그나마 다행이지 않은가. 물론 입장차에 따라 갑이나 경영진은 개발자의 무능으로 몰아가기도 한다. 왜 모든 프로젝트는 결국 시간과 자원이 부족해지는 것일까?

 

- 너무 늦게 개발한다.

개발 초기엔 낙관론이 지배한다. 요구사항을 분석한다, 자료를 모은다 하며 일을 시작하지만 실제 개발에 들어가지 않았으니 요구사항을 받아도 정확히 분석하기 어렵다. 그렇게 열심히 허송세월(?)을 보내고 난뒤 본격적으로 개발에 들어간다. 실 개발에 들어가야할 시간을 상당히 허비한 후 무수한 삽질을 통해 정확히 고객이 원하는 것이 무엇이고 어떤식으로 개발해야 할지 알게 된다.

 

- 너무 빨리, 깊게 개발한다.

개발에 들어가면서 요구사항을 굉장히 상세히 개발한다. 화면이 200개에 달하는 관리 프로그램이라고 하자. 그중 10개의 화면을 완전히 개발한다. 그야말로 퍼펙트하게...... 그리고 사용자에게 보여준다. 사용자는 갸우뚱 한다 "전체적으로 연동이 안돼서 잘 모르지만 대략 맞는것 같네요."  자 이제 화면 하나씩, 하나씩 꼼곰히 개발하여 전체 구조를 단단히(?) 정의 한다.

다시 사용자에게 보여준다. 이제야 사용자는 깨닫기 시작한다. 이게 아니라는 것을. 자 이제 핵심 구조를 대대적으로 뜯어 고쳐져야 한다.

 

애도한다. 아마 프로젝트 일정은 거의 막바지에 도달해 있을 것이다. 아 다시 개발한다면 성공할 텐데...... 하지만 세상에 동일한 프로젝트는 없으며 다시 개발할 일은 아마 없을 것이다.

 

  • 성공하려면?

모든 성공에 바탕에는 최선을 다하는 자세가 필요하다. 어떤 방법론도, 어떤 기법도 최선을 다하려는 마음이 없다면 대부분의 영특한 개발자는 남을, 그리고 스스로를 기만하게 된다. 최선을 다하려는 마음을 가지고 있다는 전제하에 개발 환경을 구축한 뒤에는 다음의 방법들이 필요하다.

 

- 첫날부터 개발한다.

점점 개발 일정은 줄어든다. 요구사항은 늘어날 것이며 또한 개발 도중 변해간다. 요구사항이 변하는 것이 이상한 것이 아니라 당연한 것이다. 변화하는 요구사항에 대응하기 위해 많은 코딩을 해야 하므로 첫날 부터 개발한다. 예를 들어 어떤 회원 관리 프로그램을 개발한다고 하자. 아직 비지니스 로직은 아무것도 모른다. 아는 것은 단 하나 회원관리 프로그램이라는 것이다. 그렇다면 나는 코딩을 시작한다. 아마 다음과 같은 클래스를 만들것이다. class MemberManager ...... 그리고 몇가지의 당연한 맴버 클래스들과 함수들...... 이정도면 첫날의 코딩으로는 충분할 것이다. 그리고 지속적으로 다듬어 나간다.

 

- 느슨하게 아는데까지만 개발한다.

위에서 이야기한 회원관리 프로그램에서 회원의 개인 정보를 상세히 관리할 필요가 있다는 것이 파악되었지만 아직 무엇인지 모른다.

그렇다면 개인정보 관리자 클래스를 만들어서 맡긴다. 계속 잘 모르는 기능들은 그것을 위임하는 객체를 만들고, 상위 클래스만이 인터페이스로서 접근될 수 있도록 한다. 아마 문제가 생기면 상위 클래스의 접근 함수를 몇개 교체하는 것으로 끝날 수 있을 것이다.

 

- 두번 개발한다.

느슨하게 개발하여 전체적인 모습을 보여준다. 중요한 것은 실제 작동하는 프로그램을 사용자에게 보여주는 것이 전체 개발기간의 1/5 - 1/3을 넘지 않아야 한다는 것이다. 1) 고객에게 대략적이지만 전체적으로 작동하는 프로그램을 보여주고, 2) 사용자와의 피드백을 통해 개발자는 전체 프로그램의 명확한 윤곽을 파악하고 3)고객이 무엇을 원하는지 알게 되면서 더 나아가서 4)고객이 원하지만 생각하지 못했던 개선까지도 추가로 반영할 수 있게된다. 5)느슨함을 유지하며 점진적이며 점증적으로 두번째 개발을 진행 한다.

아마 이전 대부분의 코드를 재활용 할 수 있으면서 마치 스크립트를 짜듯이 프로그램을 구성할 수 있을 것이다.

 

축하한다. 아마 전보다 더 많은 코드를 구성하면서도 결함은 적고, 사용자는 좀 더 만족할 것이다. 더불어 당신의 가치도 높아질 것이다.

 

+ Recent posts