'생산성'에 해당되는 글 1건

  1. 2010.01.21 [펌]생산성 높은 소프트웨어 개발

[펌]생산성 높은 소프트웨어 개발

Legacy 2010. 1. 21. 09:59

원본 출처 : http://itviewpoint.com/153896

출처: 漁夫의 'Questo e quella'; Juvenile delinquency : 뜻을 이해하기 곤란한 리플


생산성 높은 소프트웨어 개발

제조업의 경우 생산 현장의 생산성을 높이기 위해 인력을 추가하고 생산시설을 확충하면 그 만큼의 생산성은 향상된다. 그러나 소프트웨어 개발에서는 개발 지연이 되어 개발자를 더 투입하면 개발 일정이 더 길어져 소프트웨어 인력 충원에 따른 생산성 향상을 기대하기 힘들다. 그 이유는 결과물인 소프트웨어는 개발자의 지적 활동이 많은 부분을 차지하기 때문이다. 그러므로 프로세스를 통해 통제해 보려고 하지만 쉽게 통제되지 않는다. 생산성 향상을 위해 통제가 아닌 소프트웨어 개발에 필요한 몇 가지 중요한 점을 이야기해 보고자 한다.

김성 sung21.kim@samsung.com|삼성소프트웨어멤버십 회원으로 활동한 바 있고, 현재는 삼성전자에서 근무하고 있다.  Enterprise Architecture 개발과 관련된 실무 경험을 갖고 있으며 소프트웨어 공학 분야에 관심이 많다.

팀을 만들 때 자신의 의견을 강하게 주장하는 유능한 팀원으로만 구성된 팀과 유능하지는 않지만 경청하고 소통하는 팀원만으로 구성된 팀 중 어느 팀이 프로젝트를 성공할 확률이 높을까?

의사소통

정답은 후자이다. 전자의 경우 팀원 개개인의 능력은 우수하지만 서로 자신의 의견을 굽히지 않고 협업하지 않아 팀원 간의 불협화음이 일어나고 결국 의사소통 단절로 이어진다. 

자신들의 의견이 의사결정에 반영될 수 있도록 자신의 목소리를 높이다 보니 의사결정이 되지 않고 계속 지연되는 일이 발생하고 의사 결정에 자신의 의견이 반영되지 않으면 팀에 대한 부정적인 입장으로 프로젝트에 참여하게 된다.

후자의 경우는 문제에 대해 서로 협의하고 해결점을 찾는 과정에서 의사결정이 이뤄지며, 이 과정에서 서로의 신뢰와 업무능력 향상이 함께 이뤄진다.

서로의 의견에 대해 계속적인 피드백을 서로에게 주며 모든 팀원이 공감하고 합의하는 결과에 도달해 서로간의 관계는 더욱 두터워져 의사소통이 원활하게 이뤄진다. 

그러므로 결과에 대해 누구도 불만을 품지 않으며 모두 적극적인 자세로 프로젝트에 임하게 된다. 이처럼 프로젝트의 성패는 개개인의 능력이 아니라 원활한 의사소통을 통한 협업에 있음을 기억해야 한다.

정확한 의사소통이 이뤄지지 않으면 Integration되는 소프트웨어의 많은 부분에서 오류가 발생하고 이를 해결하기 위해 많은 시간이 소요된다. 

이는 다시 말해 의사소통의 중요성을 의미하지만 다른 각도에서 생각해보면 의사소통에 어려움 있다는 의미다. 

의사소통의 어려움을 줄이기 위해 최대한 개발하는 모듈에 대한 연관성을 줄인다면 생산성을 더 높일 수 있을 것이다. 

소프트웨어 설계 시 Feature 단위의 정의로 소프트웨어 모듈간의 의존성을 낮추고 계층구조의 소프트웨어를 만들어 최소한의 인터페이스 규약만을 정확히 정의한다면 의사소통의 불협화음을 최소화할 수 있을 것이다.

코드 리뷰

Pair 프로그래밍을 해본 경험이 있는가? 

Pair 프로그래밍은 하나의 모니터 앞에 두 사람이 앉아 한 사람은 코드를 작성하고 한 사람은 코드를 보면서 함께 고민하는 방식으로 이뤄진다. 

장기에서 훈수를 할 때 장기판의 말이 잘 보이는 것과 같이 코드를 지켜보는 사람은 코딩하는 사람의 오류를 잘 찾아낼 수 있다는 장점이 있고 자동적으로 백업된다. 

그래서 처음에는 두 사람이 하나의 작업을 같이 하므로 생산성이 떨어지는 것 같이 느끼지만 품질 향상을 통해 프로젝트 후반부에서는 생산성이 좋아진다. 

그러나 효율적인 Pair 프로그래밍을 하기 위해서는 몇 가지 조건이 만족되어야 한다. 

첫째, 작업을 함께 할 수 있는 시간적, 환경적 배려가 필요하다. 

개발자는 현재 프로젝트의 개발만을 하지 않는다. 

자신에게 할당된 여러 가지 업무가 있으며, 그 업무를 모두 처리하기 위해 자신만의 스케줄로 업무를 진행해 나간다. 개인이 맡은 업무가 서로 상이하고 공통된 업무의 범위가 작으면 서로 만날 수 있는 시간조차 없다. 

그리고 좁은 작업 공간에서 그리고 작은 모니터에서 두 사람이 앉아서 개발하는 것도 함께 개발하는 것을 힘들게 한다. 

미국 유타대에서 문서 편집 등의 작업을 할 때 모니터 크기가 바뀌면 생산성이 어떻게 달라지는지 측정하는 연구를 했다.

24인치 모니터를 쓰는 사람이 18인치 모니터를 쓰는 사람보다 52% 빠르게 작업을 끝마쳤고, 20인치 듀얼 모니터를 쓰는 사람이 18인치 모니터 한 개만을 쓰는 사람보다 44% 빠르게 업무를 끝냈다고 한다. 

이러한 연구 결과와 같이 개발환경 문제는 생산성에 영향을 주므로 생산성을 높일 수 있는 환경을 마련하는 것 또한 중요한 일중의 하나이다.

둘째, 서로 친해야 한다. 개발자는 자신의 코드에 대해 제3자가 비판하는 것을 아주 싫어한다. 

그러므로 함께 일하는 사람이 친해서 소스 코드의 잘못된 점 등을 부담 없이 이야기할 수 있고 받아들일 수 있어야 한다. 

그렇지 않아도 보기 싫은데 같이 앉아서 작업하라고 한다면 서로 입을 다물고 아무런 대화가 없어 함께 작업하는 의미가 사라진다.

셋째, 개인의 능력 차를 고려해야 한다. 

개인의 능력 차가 너무 많이 나면 능력이 낮은 사람은 무조건 배우는 자세로 임하게 되고 어떠한 지적이나 조언을 할 수 없게 된다. 

넷째, 개발 인력이 충분해야 한다. 프로젝트가 작아 개발자가 한 두 명이 개발하는 소프트웨어도 많다. 그럴 경우는 Pair 프로그램이 불가능하다.

이러한 제약사항들이 있으니 현 상황을 잘 파악해 적용 유무를 결정해야 한다. 

서로 백업되고 소프트웨어 품질을 향상시켜 생산성을 높인다는 목적을 달성하기 위해서는 코드 리뷰도 좋은 방법이다. 

코드 리뷰를 통해 서로의 코드를 공유하고 선임자에 의해 코드의 잘못된 부분의 지적과 조언을 할 수 있어 소프트웨어 품질을 향상시킬 수 있다. 

또한 다 작성된 코드로 코드 리뷰하는 것은 시간적으로도 많이 절약된다. 

또한 혼자 개발하는 경우에도 자신이 작성한 코드를 직접 리뷰하는 방법으로 진행할 수 있으며 이 방법으로 자신이 작성한 코드의 오류를 미리 발견해 수정하는 것이 가능하다. 

상황이 여의치 않아 Pair 프로그래밍을 할 수 없더라도 코드 리뷰를 한다면 충분히 생산성 향상을 가져올 수 있다.

교육

수행 능력은 개인에 따라 3배에서 10배까지 차이가 날 수 있다고 하듯이 소프트웨어 개발에서의 개인 생산성은 많은 차이를 보이고 있다. 

그러나 이러한 수행능력을 판단하기가 어렵다는 게 문제이다. 

그 결과, 정확한 수행능력치를 기준으로 일정에 반영하기가 어렵다.  

똑같은 일을 A라는 사람은 1시간 만에 해결하는데 반해 B라는 사람은 5시간이 걸려야 처리할 수 있다. 

그렇다고 해서 A라는 사람이 무조건 수행능력이 낮다고 할 수는 없다. 

각 사람마다 잘하는 분야가 있기 때문에 다른 일에 대해서는 더 나은 성과를 보일 수 있기 때문이다. 

이러한 개개인의 능력을 잘 파악하고 적재적소에 인력을 잘 할당하는 것은 개인의 생산성을 최대한 높일 수 있는 방법이다. 

그러기 위해서 개인의 능력을 향상시키기 위한 교육이 지속적으로 이뤄져서 교육을 통해 얻은 지식을 업무에 활용해 더욱 높은 성과를 얻도록 해야 한다.

그러나 교육도 무조건 진행하는 것이 아니라 개인마다의 업무에 필요한 전문 분야를 선택하도록 하고 전문 분야에 대한 지속적인 교육과 업무를 통해 전문가로 양성해 가야 한다. 

방향 없는 교육은 단순히 자신의 지식을 늘릴 뿐 업무에 도움은 되지 않으며 시간이 지나면 모두 잊어버리게 된다. 

업무의 테두리 안에서 전문 분야를 선정하고 전문 분야의 담당자에 대한 지속적인 교육이 이뤄질 때 개발자에 대한 생산성 향상으로 개발자와 기업 모두가 윈-윈 할 수 있다.

리더의 자세

팀을 이끌기 위해서는 리더의 역할이 무엇보다도 중요하다. 

팀의 리더는 조직 구성원의 능력을 최대한 끌어 낼 수 있어야 한다.

지시나 통제가 아닌 조언하고 지원하는 자세로 팀을 이끌어야 한다. 

지식사회가 되면서 이제는 수직적인 조직에서 수평적인 조직으로 되어가고 있다. 

이는 업무가 전문화되어 감에 따라 업무담당자가 맡은 일에 대해 가장 많이 알고 잘 할 수 있기 때문이다. 

이는 점점 지시와 통제를 통해 조직을 이끌어 가기 힘들다는 뜻이 된다.

이제 진정한 리더는 지시와 통제로 팀을 이끄는 것이 아니라 mento와 Supporter로서 조언하고 지원하는 자세로 바뀌어야 할 것이다. 

그러나 아직 수직적인 조직체계 뿐만 아니라 강한 리더십을 위해 더욱 강한 지시와 통제를 가하는 경향이 있고, 그렇다고 개발자가 쉽게 지시와 통제에 따르지도 않는다. 

그러므로 개발자에게 책임과 권한을 적절하게 부여함으로써 개발자의 주인의식을 높여 능동적 자세를 이끌어 내는 것이 더 중요하다.

또한 리더는 비전 제시자가 되어야 한다. 무조건 ‘나를 따르라’는 시대는 지났다. 

팀원에게 정확한 비전을 제시하고 비전을 공유해 그 비전이 팀원 개개인에 맞을 수 있도록 조정하며 비전을 향해 한 방향으로 힘이 결집될 수 있도록 해야 할 것이다. 

비전을 공유하고, 비전을 바라보고, 팀이 한 방향으로 한 몸같이 움직일 때 진정한 팀의 파워가 생겨나게 된다.

또한 중요한 것 중의 하나는 경청이다. 담당자는 해당 업무에 관해 많은 고민을 하고 시행착오를 겪으면서 많은 것을 경험하며 현장의 소리를 가장 가까이에서 들을 수 있다.

그래서 그 의견은 보석보다도 더 귀히 여겨져야 하지만 의사결정자는 자신의 의견과 맞지 않을 때 바로 무시하게 된다. 

반복적으로 의견이 무시되면 팀원은 수동적인 태도로 바뀌게 되고, 결국에는 개선과 혁신에 대한 생각도 행동도 하지 않게 된다. 

팀원이 마음껏 생각하고 마음껏 뛰어 놀 수 있게 만들어 주는 것이 진정한 리더의 임무가 아닐까 생각해 본다.

재사용

소프트웨어의 생산성과 품질을 향상시키기 위해 모듈화, 유연하고 확장 가능한 구조로 개발하려는 노력이 계속되어 왔으며, 최근에는 소프트웨어 재사용을 위한 노력 또한 활발하게 진행되고 있다.

소프트웨어 재사용은 최종 산출물에 대한 재사용이므로 요구사항 분석에서부터 테스트에 이르기까지 모든 결과물에 대한 재사용을 의미한다. 

모든 결과물에 대한 재사용은 생산성 및 품질 향상에 많은 영향을 미치게 된다. 재사용 가능 컴포넌트와 변경 가능 컴포넌트를 분류해 설계하고, 아울러 추가나 수정에 의해 최소한의 영향만을 받도록 컴포넌트를 설계해야 한다. 

보통 재사용을 위해 자신이 필요한 소스 코드를 이른바 ‘Copy & Paste’해서 다시 사용하는데, 이를 재사용이라고 보기에는 무리가 있다.

‘Copy & Paste’는 단순 일부 소스만을 재사용할 뿐이고 추가되는 소스에 맞게 수정이 이뤄지는 경우가 많다. 그러므로 요구사항 분석부터 테스트에 이르는 모든 결과물에 대한 재사용이 될 수 없다.

소프트웨어에서 공통적으로 많이 사용되는 부분이 재사용되는 대상이 된다. 

그러므로 재사용하기 위해 모듈화하게 되는데, 모듈화는 공통적으로 사용하는 모듈과 시스템에 가변적으로 사용하는 부분으로 나눠 정의해야 한다. 

공통적으로 사용하는 모듈의 경우는 사용자의 요구사항 변화에 많은 영향을 받지 않으므로 재사용 대상으로 선정해 모듈화하고 재사용할 수 있도록 한다.

데이터를 송신하고 수신하는 기능을 재사용하겠다고 해서 Sender와 Receiver 모듈을 재사용한다면 Sender와 Receiver는 다른 모듈과의 의존성을 가질 수 있으며, 이에 대한 정보를 알아야 사용이 가능하게 된다. 

따라서 이러한 의존성이 관리되어야 하므로 오픈되어야 한다. 그러나 이를 하나의 프레임워크 단위로 만들고 재사용한다면 이러한 의존성을 사용하는 측에서는 고려할 필요가 없으므로 더욱 추상화시킬 수 있다. 

모듈화된 컴포넌트를 다른 연동 시스템에서 사용한다면 소프트웨어 재사용으로 인해 개발시간을 단축시킬 뿐만 아니라 재사용하는 코드는 재사용 컴포넌트가 갖는 품질의 수준을 그대로 얻을 수 있게 된다.

1.jpg

소프트웨어 재사용은 소프트웨어를 조립 가능하게 하는 것이다. 메인 프레임워크를 만들고 메인 프레임워크에 추가되는 기능을 소스의 수정 없이 플러그인 형태로 꼽아서 쓸 수 있도록 설계되고 개발되어야 한다. 메일 프레임워크에 기능이 추가될 때마다 기능 단위 모듈을 꼽아 Integration되어야 하는데, Integration은 configuration file 내에 명령과 호출되어야 할 컴포넌트의 매핑을 통해 가능하다.

2.jpg

재사용되는 모듈은 내부 또는 외부에서 활용 가능하므로 재사용 모듈에 대한 정확한 설명과 인터페이스 정의가 필요하며 이에 대한 매뉴얼이 필요하다. 재사용 모듈을 효율적으로 관리하기 위해서는 모든 구성원이 공유할 수 있는 저장소를 만들어 재사용 모듈에 대한 정보와 함께 관리하고 쉽게 검색해 사용할 수 있도록 하는 것 또한 중요하다

Complexity

소프트웨어 복잡성(Complexity)을 갖게 하는 것에는 무엇이 있을까? 

Complexity는 다양한 각도에서 생각해 볼 수 있다. 소프트웨어의 복잡성이 높아지면 개발 단계뿐만 아니라 유지보수 단계에서 많은 비효율성을 갖게 된다. 소프트웨어 복잡성을 높이는 이유로 다음 몇 가지를 들 수 있다.

첫째, 조건문의 증가이다. 조건에 따른 서로 다른 처리를 위해 조건문을 사용한다. 

처음에는 한 두가지 조건에서 시작한다. 그러나 시간이 갈수록 기능이 추가되고, 그에 따른 조건문도 추가된다. 

조건의 항목이 추가되면서 계속적으로 추가하다 보면 어느새 조건문이 많아진다.  이는 소프트웨어의 복잡성을 높이는 것이며, 이로 인해 시스템의 성능을 떨어뜨리는 원인이 된다. 

계속해서 추가할 수밖에 없다고 생각할 수 있지만 이는 분명 여러 개의 조건문으로 분리할 수 있다. 

불필요한 조건문을 최소화하고 분리해 간단한 구조를 만들어야 한다. 

한 클래스 안에 수많은 조건문의 반복을 없애야 한다. 하나의 모듈 내에 조건문이 많다는 것은 모듈 안에 서로 분리 가능한 기능이 함께 있을 가능성이 높다는 것이고, 이는 기능 분리를 통해 모듈로 분리한다면 자연스럽게 조건문이 분리된다. 

소프트웨어 개발 중 반복적인 추가와 변경을 통해 모듈이 비대해지고 복잡해지면서 여러 기능이 혼합되고 추가되어 조건문이 많아지고 복잡해진다. 기능별 모듈을 적정하게 분리해 가면서 추가해 나간다면 소프트웨어 복잡성이 높아지는 일은 미리 막을 수 있다.

둘째, depth의 증가 및 역 참조 구조이다. 

오래전 소프트웨어 개발 시 한 시대를 풍미했던 GOTO 문을 기억하는가?

GOTO 문의 편리함으로 많이 사용되었지만 GOTO 문의 사용이 많을 경우 호출이 복잡해져서 소스의 복잡성이 가중된다는 큰 단점이 있었으며, 이로 인해 GOTO 문은 사라진 지 오래이다. 

소프트웨어의 소스 코드는 프레임워크에서 지원하는 함수와 개발자 자신이 필요에 의해 만든 수많은 함수를 호출하는 코드로 이뤄져 있다. 

소프트웨어의 call depth가 증가한다는 것은 호출된 함수에서 또 다시 다른 함수로, 그리고 또 다시 다른 함수로 계속적으로 호출하는 것을 의미한다.

이러한 복잡한 호출은 GOTO 문을 쓰는 것과 다를 바 없다. 소스 코드 분석을 위해 추적해 보면 느끼겠지만 이렇게 되면 상당히 복잡하고 소스를 읽기 어렵게 된다. 

또한 단위 테스트 시에도 오류가 어느 지점에서 발생했는지 확인하기 어려우며, 확인을 위해서는 호출되는 마지막 함수부터 추적해야만 문제를 찾을 수 있게 된다. 이렇듯 call depth의 증가는 소스를 복잡하게 해 읽기 어렵게 할 뿐만 아니라 테스트 코드를 만들기 힘들며 디버깅도 힘들게 한다.

3.jpg

소프트웨어 계층별로 Layer를 나누어 개발하는 Layered Architecture는 계층 간의 의존성을 최소화해 변경에 유연하게 대응하고자 하는 목적이 있다. 계층에서의 참조는 같은 계층 간 또는 하위 계층으로의 참조로만 이뤄져야 한다. I3에서 M2를 참조하는 것과 같이 하위 계층에서 상위 계층으로의 역참조가 일어나서는 안 된다. I2에서 I3으로 같은 계층에서의 참조는 문제가 되지 않는다.

4.jpg

상위 계층으로 갈수록 추가 및 변경이 자주 일어나며 하위 계층은 다른 모듈에 의해 여러 참조를 갖기 때문이다. 역참조가 일어날 경우 상위 계층이 바뀌면 역 참조를 한 하위 계층이 바뀌게 되며 이를 참조한 다른 계층의 모듈까지 연쇄적으로 변경되어야 한다. 이는 유연성을 떨어뜨리며 복잡성을 가중시킨다.

셋째, Unused 코드 증가이다. 개발된 코드를 받고 분석했던 경험이 다 있을 것이다. 코드를 보다 보면 이걸 사용하는지 사용하지 않는지 모를 때가 많다. 심지어는 자신이 작성한 코드 또한 사용하는지 사용하지 않는지 모를 때가 많다. 코드를 한참 따라가며 분석하다 보면 어느 순간 사용하지 않는 코드임을 알게 된다. 그래서 사용하지 않는 소스로 인해 많은 복잡함을 느낄 수 있다. 개발하면서 사용하지 않는 코드가 있더라고 왠지 지우면 무슨 일이 벌어질 것 같고, 다음에 또 사용할 수도 있을 것 같으며 ‘굳이 지울 필요가 있을까’라는 이유로 사용하지 않는 코드를 그대로 방치하게 된다. 이렇게 사용하지 않는 코드는 레거시 코드를 분석하다 보면 상당히 많은 것을 확인할 수 있다. 사용하지 않는 코드를 방치해 소프트웨어의 복잡성을 높이지 말고 사용하지 않는 코드는 과감히 삭제한다든지 전체를 주석 처리해 사용하지 않는다는 것을 확실히 표시함으로써 소프트웨어 복잡성을 낮출 수 있다. 코드 분석 툴을 사용해 사용하지 않는 코드를 주기적으로 분석하고 관리해 Unused 코드의 비율을 낮추어야 한다.

넷째, 소스의 크기와 소스간의 의존성이다. 소스의 크기가 작을수록 단순해 보일 뿐 아니라 유연성이 높고 변경하기 쉬워진다. 소스의 크기가 크면 복잡해 보이는 것이 사실이다. 그러나 소스 크기만을 가지고 복잡성이 높고 낮음을 얘기할 수는 없다. 소스의 크기가 작더라도 소스간의 의존성이 높다면 하나의 기능을 추가하거나 변경하는 것이 여러 개의 소스에 걸쳐 영향을 주어 추적해가며 수정이나 변경이 이뤄진다. 그리고 패키징과 릴리즈하는 컴포넌트의 수가 많아져 이 또한 복잡성을 가중시키게 된다. 소스의 크기가 크더라도 의존성을 갖지 않고 내부적으로 잘 분리되어 있다면 수정이나 변경이 용이할 수 있고 패키징과 릴리즈를 할 때 하나의 컴포넌트만 하면 되므로 복잡성이 줄어들게 된다. 소스 크기를 무조건 줄이려고 하는 것이 아니라 소스간의 의존성을 최대한 줄이면서 소스의 크기를 줄여나갈 때 복잡성을 낮출 수 있게 된다.

다섯째, 예상하지 않은 코드의 증가이다. 예상하지 않은 기능의 추가와 예상하지 않은 기능의 변경은 기존 설계 및 구현된 소스에 변경을 가져온다. 예상치 않은 요구사항을 반영하기 위해 소프트웨어 변경이 불가피하게 되고, 이러한 상황에서는 일정 또한 급박하게 돌아간다.  그렇게 되면 다급해진 개발자는 기존 소스에 끼워 넣기 식으로 개발을 진행하게 된다.  Feature별로 구분해 개발했는데 적합한 Feature도 없으니 아무 것이나 적당한 Feature를 선택해 추가하기 시작한다. 이렇게 추가된 소스는 기존의 잘 정리된 소스를 복잡하게 만들게 된다. 소프트웨어를 설계하는 데 있어서 모듈을 나누고 소프트웨어 의존성을 낮추는 등의 설계는 변화에 유연하게 대응할 수 있어 수정 시 드는 비용을 낮추기 위한 방안이지 실제적으로 변화에 대응하기 위한 방법은 아니다. 변화에 대응하기 위해서는 요구사항의 변화 시 소프트웨어 수정의 최소화에 초점이 맞춰져야 하고 변경 가능성 있는 부분을 미리 고려해 소스 수정을 최소화하면서 확장 가능해야 한다.

그럼 소프트웨어 변경 유형에는 무엇이 있을까? 기능의 추가, 기능의 삭제, 기능의 변경, 설계 미흡이 있는데, 기능의 추가나 삭제는 기존의 소스 구조의 변경 없이 가능하지만 기능의 변경은 많은 문제를 유발한다. 그리고 기능의 추가가 독립된 기능 추가가 아닌 기존의 기능에 더해지는 경우에 문제가 될 수 있다.

기능의 변경과 기존 기능에 기능이 더해지는 경우의 예는 처리 로직의 Rule을 변경하는 것에서 많이 찾아볼 수 있다. 이러한 Rule의 변화가 소프트웨어 변경의 원인이 되므로 요구사항 분석 및 설계 시점에 Rule에 대한 정확한 정의가 필요하고 Rule의 변경이 발생하더라도 쉽게 소스 코드를 변경하거나 변경을 수용할 수 있는 구조로 만들어야 한다. 그럼 Rule의 변경은 왜 발생하는 것일까? Rule은 요구사항으로부터 나오고 요구사항으로부터 변경되는 만큼 요구사항 분석 시 충분한 리뷰를 통해 요구사항이 정확하게 반영된 Rule을 정의하고 이해당사자 모두와 공유해야 한다.

참고자료
1. Addison Wesley, UML Distilled Third Edition, 2003
2. Addison Wesley, Designing Software Product Lines With UML, 2004
3. WILEY, Architecting Enterprise Solutions, 2004
4. 영진닷컴, 객체지향 CBD 개발 방법론, 2004
5. 위키북스, 똑똑하고 100배 일 잘하는 개발자 모시기, 2007
6. 인사이트, 익스트림 프로그래밍 2판, 2006


: