'프로젝트관리론/프로젝트수행'에 해당되는 글 9건

  1. 2011.12.22 제대로 된 모바일 어플리케이션 개발을 위해 필요한 역할들~ (1)
  2. 2008.09.15 프로젝트의 성공 요인 분석 #2
  3. 2008.09.15 프로젝트의 성공 요인 분석 #1
  4. 2008.08.28 프로젝트에 이름을 지어주자~
  5. 2008.02.27 애자일.. XP.. 잘 안되는 이유는 뭘까요? (1)
  6. 2007.10.18 자주 리펙토링을 하라.(3)
  7. 2007.10.16 자주 리펙토링을 하라.(2) (1)
  8. 2007.10.13 자주 리펙토링을 하라.(1)
  9. 2007.08.19 테스트 코드.. 우선 개발할 것인가?

제대로 된 모바일 어플리케이션 개발을 위해 필요한 역할들~

|



모바일 시장이 발전하면서 개인도 모바일 App을 만들어서 돈을 벌 수 있게 되었습니다.
그러나 제대로 된 서비스를 만들려면 어떠한 역할들이 필요할 지 한번 정리해 봤습니다. 

1. 기획 (Planning)

- 새로운 서비스/시스템을 기획
- 일반적인 아이디어를 보다 실현 가능하도록 구체화 함 
- 서비스 기획안, 화면 구성 방안 및 사용자 매뉴얼 등을 작성 
 독서량이 많아야 한다. (다양한 분야의 도서를 읽어야 함)
 기존의 서비스를 많이 사용해 봐야 한다.
 기획하려는 분야의 전문가가 되어야 한다. 
 좋은 아이디어를 선별할 수 있는 판단력이 있어야 한다.
 기획하는 서비스에 대한 시장 조사 능력이 있어야 한다.
 
2. 디자인 (Design)

- 디자인은 단순히 그림을 그리는 것이 아님
- 디자인은 해당 서비스의 이미지를 구축함으로써 성공 여부를 결정함
- UI/UX에 대한 디자인을 수행 (사용자 경험 중시)
 Best Practice와 같은 좋은 디자인을 많이 봐야 한다.
 개발자가 아닌 사용자를 고려하여 서비스를 디자인 해야 한다.
 다양한 입력 방식과 같은 새로운 사용자의 경험을 반영해야 한다.
 매번 새로운 디자인 스타일을 구축해야 한다. 
 웹과 모바일은 디자인에 있어 화면의 크기를 고려해야 한다. 
 
3. 설계 (Architecture)

- IT 서비스를 위해서 개발보다 중요한 것이 설계임 (잘못된 설계는 추후 엄청난 손실을 가져옴)
- 보통 설계자는 개발자보다 많은 경험을 가지고 있음
- DB 설계, Framework 설계, 기능 설계 등을 수행함
 플랫폼(DB, 프로그래밍 언어, 시스템)에 대한 상세한 분석이 필요하다.
 새로운 기술의 등장과 함께 누구보다 먼저 연구해야 한다.
 서비스의 효율을 결정하는 분야이므로 성능 개선에 항상 관심을 가져야 한다.
 DB / OS / 네트워크 / 프레임워크 등 각 분야별로 전문가가 되어야 한다.

 4. 개발 (Development)


- 실제로 서비스나 시스템을 위한 프로그램을 개발하는 분야임
- 프로그래밍 환경은 끊임없이 변화하고 있으므로 빠른 대응이 필요함
- 서비스 가능한 프로그램을 개발함

 프로그램 개발을 위한 기술을 습득해야 한다. 
 개발 관련 기술은 끊임없이 변하므로 꾸준히 학습해야 한다. 
 기존의 API를 최대한 활용하여 개발의 생산성을 높여야 한다. 
 과거 수행한 개발 내역을 자산화 하여 유사한 프로그래밍에 재사용 해야 한다.
 
5. 테스트 (Test)

- 현대의 IT 환경에서 테스트의 중요성이 점차 강화되고 있는 분야임
- 테스트는 정상적인 상황 뿐만 아니라 비정상적 환경에서도 수행해야 함
- Black Box 테스트, 경계 테스트, 예외 처리 테스트 등을 수행함
 테스터는 상당한 끈기와 노력을 요구하는 분야이다. 
 테스트의 중요성에 비해 다른 분야보다 대우를 받지 못하기도 한다.
 테스트 시나리오를 작성하고 이에 따라 철저하게 테스트를 수행해야 한다.
 테스트에서 찾지 못한 오류를 서비스 개시 후 발생하게 되면 손실이 크다. 

6. 운영 (Operating)

- 서비스의 지속적인 발전을 위해서 운영 업무를 수행해야 함.
- IT 분야에서 운영은 하드웨어와 같은 시스템 모니터링 및 장애 대응과 같은 것을 포함함.
- VOC 운영, 시스템 운영, 유지 보수 운영 등의 업무를 수행함

 하드웨어 시스템에 대한 많은 지식을 가지고 있어야 한다.
 시스템 모니터링, 장애 대응, 네트워크 모니터링을 위한 기술들을 습득해야 한다.
 개발을 지원하기 위한 서버 구성 등도 수행해야 한다. 
 고객 대응의 경우, IT 분야는 아니지만 서비스 운영에서는 필요하다.  
 




Trackback 0 And Comment 1

프로젝트의 성공 요인 분석 #2

|



지난 글에서 프로젝트 성공 요인 중 변경관리, 희의관리, 이해관계자, 변화관리에 대해서 살펴봤습니다.
이번에는 이슈화, 리스크관리, 인적자원, 현실과 지표의 괴리에 대해서 알아보겠습니다.

다시 한번 출처를 언급하면 2004년 월간 시사컴퓨터에 기고된 천장락 교수님의 글을 정리해서 옮겨놓은 것입니다.

5. 사소해 보이는 문제도 '이슈화' 하자

프로젝트를 진행하다가 여러 가지 사정으로 계획과는 다르게 진행되거나, 계획대로 진행하기가 곤란한 문제가 발생했을 때 이슈가 발생했다고 합니다. 또 어떤 것이라도 일정에 차질을 주게 되면 이슈로 인식해야 한다고 합니다.

이러한 이슈를 관리하는 절차는 다음 6단계로 되어 있다고 합니다.

이슈 발생 인지 -> 이슈 분류 -> 대응 방안 수립 -> 대응 방안 실행 -> 실행 모니터링 -> 이슈 종결 내용 공지

이슈가 문제가 되면 리스크(위험)이 됩니다.
그럼에도 불구하고 이슈가 발생할 것 같으면 쉬쉬하고 내부적으로 해결해 보려는 노력을 많이 합니다.
프로젝트에서는 이슈가 언제든지 발생할 수 있습니다. 이런 문제를 내부에서만 조용히 해결하려다 더 큰 문제가 많이 발생할 수 있습니다.
사소한 이슈라도 제대로 파악하고 챙기는 프로젝트 관리자가 되어 보시기 바랍니다.

이슈화 전체보기..

6. 프로젝트의 조기 경보기 "리스크 관리"

리스크를 프로젝트나 프로젝트 내의 일부분이 정해진 기간 내에 주어진 예산으로 완료되지 못할 위기에 빠질 수 있는 정도나 기대한 성과가 달성되지 못할 가능성이라고 정의하고 있습니다.

프로젝트 특성상 발생할 수 있는 리스크에 대해서 비슷한 프로젝트를 진행한 경험에서 축적된 지식으로 예측할 수 있으며, 이렇게 예측된 리스크를 관리 우선 순위별로 분류해 리스크 관리 체크 항목을 가지고 리스크를 관리해 나갈 수 있다고 합니다.

그래서 미리 막을 수 있는 대응책과 실제 발생했을 때 처리 방법이 있어야 한다고 이야기 합니다.
또한, 지표를 통해 리스크를 지속적으로 모니터링 할 수 있어야 함은 기본사항이구요..

앞에서 리스크/위험 관리에 대해서는 #1, #2로 정리한 내용이 있습니다.
리스크 완화, 회피, 모니터링, 관리에 대해서 이야기 했었습니다.
이런 위험 관리는 모든 프로젝트에서 중요한 요소라고 다시 한번 강조하고 싶네요..

리스크관리 전체보기..


7. 인적 자원의 파악, 가볍게 여기면 큰 코 다친다.

의욕이 앞서 보유한 자원의 총량을 초과해 프로젝트를 수행하다 보면 프로젝트가 제대로 진행되기 어렵습니다.
특히 인적자원은 사람의 수 뿐만 아니라 그 사람이 보유한 역량의 수준까지도 파악해야 한다고 합니다.

또한 아웃소싱에 의존하는 비율도 미리 정한 것을 초과하지 않도록 해야 하는데, 이유는 추후 유지보수나 관리에 문제가 발생할 소지가 있기 때문입니다. 프로젝트의 핵심 업무는 내부 인력으로 처리하는게 바람직하다고 하네요..

프로젝트 뿐만 아니라 모든 일은 결국 사람이 해결할 수 밖에 없다고 봅니다. 프로젝트에 있어서 갑자기 인력이 교체되거나 역량이 부족한 인력으로 수행하게 되면 댱연히 문제가 발생할 수밖에 없을 겁니다.
아웃소싱에 의존하는 업체도 아웃소싱 인력의 능력에 따라 프로젝트의 성패를 맡겨야 하니 불안할 수밖에 없을 거구요..

인적자원 전체보기..

8. 현실과 지표 사이의 괴리를 메우자

프로젝트를 진행하면서 나오는 몇 % 진행되었다는 숫자에 대한 문제점을 지적하고 있습니다.
산출물 기준으로 진척도를 계산하게 되면 외형은 확인할 수 있지만, 품질은 확인이 곤란하다는 겁니다.
그리고 개발자의 감으로 진척도를 이야기 하면 테스트에 대한 부분이 포함되어 있지 않으며 객관적이지 않은 진행 상황일 수밖에 없다고 합니다.

그래서 전체 진척도와 단계별 진척도를 별도로 관리하고 테스트와 검토 단계의 비중을 높여서 계산해야 한다고 합니다.

어디서 보니까 어른들은 숫자를 참 좋아한다고 합니다. 모든 데이터를 정량화 하는 것은 프로젝트 관리에서도 중요한 작업임에 틀림없습니다.
그러나 그 정량화에는 반드시 현실이 제대로 반영되어 있어야 합니다. 그러기 위해서는 기준이 중요하고, 프로젝트에서도 개발 속도 뿐만 아니라 품질까지도 포함해야 한다는 것이죠..

현실과지표 전체보기..


이상으로 프로젝트의 성공 요인에 대해 정리해봤습니다. 일반적으로 생각하는 부분과 큰 차이가 없어서 정리해봤습니다.

여러분은 어떻게 생각하는지요? 이 외에도 중요한 요소가 있다면 댓글 부탁드립니다.




Trackback 0 And Comment 0

프로젝트의 성공 요인 분석 #1

|



2004년 5월 ~ 12월까지 월간 시사 컴퓨터에 연재된 천정락 교수님의 프로젝트 성공 요인 분석이란 자료가 있습니다.
4년여의 시간이 지났지만, 아직도 현재 진행하고 있는 IT 프로젝트에도 도움이 되는 이야기 인 듯 하여 정리해서 옮겨 봅니다.

1. 업무 변경 관리로 프로젝트 성공률을 높이자.

첫번째로 이야기 한 것은 변경 관리입니다. 프로젝트의 범위나 현업의 업무가 변경된 경우, 의사결정자들과 프로젝트 수행자들이 모여 업무 변경 관리 위원회를 만들고 체크해 나가야 한다는 이야기 입니다.

방법으로는 업무가 변경될 때마다, 단계별로, 프로젝트 막바지에 변경하는 방식이 있는데요
변경될 때마다 하는 것은 번거롭고 프로젝트 진행을 더디게 할 수 있구요.
단계별로 수행하는 것은 프로젝트가 잠시 멈추게 되므로 미리 일정을 반영해서 변경관리를 해야 한다고 합니다.
마지막에 일시에 수행하는 것은 프로젝트가 긴 경우, 업무 변경의 양도 많고 시간도 오래 걸리므로 주의해야 한다고 하네요..

어쨌든 추가 비용이 들더라도 업무 변경 관리는 어떤 형식으로든지 해야 합니다.
보통 프로젝트 수행시에 보면, 마지막에 설계 문서를 한꺼번에 다시 고치는 경우가 가장 많은 것 같습니다.
즉, 프로젝트가 끝난 후에 개발 결과물에 맞추어서 설계문서를 다시 만드는 것인데요..
실질적인 변경관리라고 볼 수는 없다고 봅니다.

정말 성공하는 프로젝트를 만들고 싶다면, 설계를 변경하는 것에 대한 위험성을 고객이나 프로젝트 수행자 모두 인식하고 초기 설계부터 신중을 기해야 할 것입니다.

업무변경관리 전체보기...

2. 회의도 관리가 필요한 시대다.

회의로 인해 낭비되는 시간의 가치에 대해서 이야기 하고 있습니다.
회의를 줄이기 위해 단순한 정보 공유는 이메일이나 인트라넷 게시판을 활용하고, 화상회의 같은 것을 충분히 활용하자는 겁니다.

만약 회의를 진행한다면, 미리 회의 목적과 내용을 회의 참석자에게 알리고, 회의의 시작과 끝나는 시간을 정해서 준수하고, 회의 끝 부분에 안건과 결론을 정리하고, 결론이 난 부분을 해당 부서나 팀에 효과적으로 전달해야 한다고 하네요..

회의가 많은 기업은 그리 성공하지 못한다는 이야기를 들은 적이 있습니다.
물론 회의라는 것이 매우 중요한 것이지만 그만큼 잘못 사용하면 탁상공론에 실행이 뒷받침되지 않는 조직이 될 가능성도 높겠죠..

회의관리 전체보기..

3. 이해관계자를 '내 편'으로 만들어라

이해관계자라 하면 고객과 같은 '프로젝트 스폰서', 프로젝트를 수행하는 '프로젝트 실행자', 프로젝트에는 직접 관여하지는 않지만 영향을 주거나 받을 수 있는 '외부 이해관계자'를 이야기 합니다.

이런 이해관계자를 명확하게 파악하고, 각자의 입장에서 프로젝트 수행에 대한 득실과 주장의 정보를 파악하고, 프로젝트에 대한 영향을 분석하고, 대응전략과 구체적인 실행방안을 세우고, 모니터링 및 피드백을 해야 한다는 겁니다.

여기에서는 주로 외부 이해관계자에 대한 이야기를 하고 있는데요..
저는 일반적으로 IT 프로젝트에 있어서 고객에 초점을 맞추고 싶습니다. 고객이라 하면 외부고객과 내부고객으로 나눠 볼 수 있을 겁니다.
내부에 같이 프로젝트를 진행하는 사람들도 하나의 고객이라고 생각하고 내편으로 만들어 업무를 진행한다면 프로젝트 진행이 좀 더 수월해지지 않을 까 합니다.

이해관계자 전체보기..

4. 프로젝트 연착륙 뒤엔 변화관리가 있다.

여기에서 변화관리는 위의 변경관리와 다른 이야기 입니다. 변경관리가 프로젝트 진행 중에 발생하는 변경 요소를 관리하는 것이라면, 변화관리는 프로젝트 완료 후 새롭게 적용되는 변화에 대한 관리를 말합니다.

프로젝트를 완료하더라도 적용해야 하는 직원들의 새로운 환경이나 제도에 대한 저항을 받을 수 있다고 합니다. 그래서 실행 과정에서 직,간접적으로 영향을 받게 되는 조직원과 고객으로부터 불편을 사게 되면 기대한 만큼의 성과를 내기도 어렵고, 조직원과 이해관계자들한테 성공했다는 평가를 받기 힘들다고 합니다.

변화를 적극 수용하고 변화에 대한 저항을 극복하며, 변화 계획을 세우고 그 계획을 차질 없이 성취해 나가기 위한 변화 관리가 필요하다고 이야기 하고 있습니다.

실제로 어렵게 프로젝트를 통해 결과물을 만들어도 제대로 활용하지 않으면 무용지물일 겁니다.
결국 만드는 것만이 최종 마무리가 아니라 제대로 필요한 곳에 적용하는 것이 성공적인 프로젝트의 마무리가 아닐까 합니다.

변화관리 전체보기..

이어서 나머지 이슈화, 리스크관리, 인적자원, 현실과지표에 대해서 정리해 보도록 할께요~
프로젝트 관리 알면 알수록 배울게 많은 것 같습니다.




Trackback 0 And Comment 0

프로젝트에 이름을 지어주자~

|



Don't call me names!
언뜻 보면 "내 이름을 부르지 마라" 일 것 같지만,
실제 의미는 "욕하지 마라", "약올리지 마라" 라는 뜻으로 사용되는 문장입니다.

names가 복수가 아닌 단수형인 name으로 사용되었다면 이름이라는 의미 그대로 쓰였겠지만,
복수가 되면서 여러개의 이름 즉, 별명으로 보기 때문에 위와 같은 뜻이 되었을 거라고 합니다.

이름이라는 것은 하나의 고유한 의미를 가져야 합니다.
그리고 이름을 지어준다는 것은 그 객체(물체이건 상황이건)에 생명력을 불어넣는 계기가 됩니다.

빅무(Big Moo)라는 책에 나오는 이야기 인데요..
뉴턴이 중력을 발견해서 유명해진 것으로 알고 있지만,
실제로 뉴턴이 발견한 것은 미적분과 반사 망원경이라고 합니다.

뉴턴은 미적분과 연금술 연구에 많은 시간을 보냈는데
오히려 그가 유명해진 것은 중력이라는 이름을 붙인 것 때문이라고 합니다.

중력이라는 이름을 부여함으로써 많은 사람들이 중력을 이용할 수 있는 기회를 준 것이죠..

한때 포탈들의 이름이 어떻게 만들어졌는지에 대한 포스팅이 유행했었는데요..
네이버는 navigate(향해하다) + 사람 접미사(er)의 합성어이고,
구글(google)은 googol이라는 10의 100제곱이라는 단어에서 유래했다고 하죠..

사이트가 성공해서 이름이 멋있어 보이는 건지,
이름을 멋지게 지어서 사이트가 성공한 건지는 모르겠네요..

여러분도 지금 하는 프로젝트에 이름을 지어주고, 의미를 부여해 보세요..
아마도 프로젝트가 한결 수월하게 진행되지 않을까 합니다. ^^

김춘수님의 꽃으로 마무리합니다.

내가 그의 이름을 불러 주기 전에는
그는 다만
하나의 몸짓에 지나지 않았다.

내가 그의 이름을 불러 주었을 때
그는 나에게로 와서
꽃이 되었다.

내가 그의 이름을 불러 준 것처럼
나의 이 빛깔과 향기에 알맞는
누가 나의 이름을 불러다오.
그에게로 가서 나도
그의 꽃이 되고 싶다.

우리들은 모두
무엇이 되고 싶다.
너는 나에게 나는 너에게
잊혀지지 않는 하나의 (의미가) 눈짓이 되고 싶다.

                                                 - 김춘수, 꽃 -






Trackback 0 And Comment 0

애자일.. XP.. 잘 안되는 이유는 뭘까요?

|



요즘 애자일 방법론이나 XP(eXtreme Programming)가 프로젝트 관리에 있어 많은 관심을 받고 있습니다.

기존의 폭포수 모델 보다는 반복을 통해 보다 빠른 피드백이 가능하고..
자동 배포, 자동 테스트를 통한 개발 생산성 향상..
짝 프로그래밍을 통한 프로그래밍 효율성 증대..
그리고 주 40시간에서 16시간 근무로의 변경..


정말 매력적인 요소가 많습니다.
특히 야근에 찌들어있는 개발자들에게는 환상적인 요소지요.

그런데 제가 이런 부분들을 적용하면서 느끼는 점이 있는데요..
개발자 스스로 입맛에 맞는 것만 취하고 나머지는 버린다는 점입니다.

대표적인 것이 주 16시간 근무와 같은 것인데요..
이것의 기본 개념은 40시간에 일할 내용을 우리는 16시간이면 처리한다는 겁니다.
그리고 남는 시간에 자기개발이나 다른 새로운 것을 시도해 보는 것이죠..

이런 가치를 공유하지 못하고, 단순히 주 16시간이라는 것에 집착하는 경우가 많습니다.
그러다 보니 반복을 통한 피드백을 하려해도..
지난주 업무가 완료되지 않아.. 계속 일이 지체되는 안타까운 일이 반복되기도 합니다.

애자일이나 XP 방법론의 성공요소는 그 내용을 아는 것이 아니라..
그 속에 포함된 가치를 서로 공유하고 실행할 때 비로소 가능해 지는 것 같습니다.

실천을 통해 우리에게 맞는 방법론으로 변화한다면,
진정 개발자나 관리자, 회사책임자들 모두 즐겁게 일할 수 있는 환경이 만들어지지 않을까 합니다.

그래서 나 자신과 우리 회사에 이런 환경이 만들어질 수 있도록 계속 시도해보고 도전해보려고 합니다.




Trackback 1 And Comment 1

자주 리펙토링을 하라.(3)

|



리펙토링을 실제로 어떻게 수행하는지.. 마틴 파울러(Martin Fowler)의 리펙토링 책에 나온 내용을 요약합니다.

여기에 정리한 내용은 인덱스 정도로 활용하시고.. 실제 리펙토링을 위한 예제나 자세한 설명은 책을 참고하시기 바랍니다.

1. 메소드 정리 (Composing Methods)

Extract Method (136)
그룹으로 함께 묶을 수 있는 코드 조각이 있으면, 코드의 목적이 잘 드러나도록 메소드의 이름을 지어 별도의 메소드로 뽑아낸다.

Inline Method (144)
메소드 몸체가 메소드의 이름 만큼이나 명확할 때는, 호출하는 곳에 메소드의 몸체를 넣고 메소드를 삭제하라

Inline Temp (146)
간단한 수식의 결과값을 가지는 임시변수가 있고, 그 임시변수가 다른 리펙토링을 하는데 방해가 된다면, 이 임시변수를 참조하는 부분을 모두 원래의 수식으로 바꾸라

Replace Temp with Query (147)
어떤 수식의 결과값을 저장하기 위해서 임시변수를 사용하고 있다면, 수식을 뽑아내서 메소드로 만들고 임시변수를 참조하는 곳을 찾아 모두 메소드 호출로 바꾼다. 새로 만든 메소드는 다른 메소드에서도 사용될 수 있다.

Introduce Explaining Variable (151)
복잡한 수식이 있는 경우에는, 수식의 결과나 또는 수식의 일부에 자신의 목적을 잘 설명하는 이름으로 된 임시변수를 사용하라.

Split Temporary Variable (155)
루프 안에 있는 변수나 collecting temporary variable도 아닌 임시변수에 값을 여러 번 대입하는 경우에는, 각각의 대입에 대해서 따로따로 임시변수를 만들어라.

Remove Assignments to Parameters (159)
파라미터에 값을 대입하는 코드가 있으면, 대신 임시변수를 사용하도록 하라.

Replace Method with Method Object (163)
긴 메소드가 있는데 지역변수 때문에 Extract Method를 적용할 수 없는 경우에는, 메소드를 그 자신을 위한 객체로 바꿔서 모든 지역변수가 그 객체의 필드가 되도록 한다. 이렇게 하면 메소드를 같은 객체 안의 여러 메소드로 분해할 수 있다.

Substitute Algorithm (167)
알고리즘을 보다 명확한 것으로 바꾸고 싶을 때는, 메소드의 몸체를 새로운 알고리즘으로 바꾼다.

2. 객체간의 기능 이동

Move Method (170)
메소드가 자신이 정의된 클래스보다 다른 클래스의 기능을 더 많이 사용하고 있다면, 이 메소드를 가장 많이 사용하고 있는 클래스에 비슷한 몸체를 가진 새로운 메소드를 만들어라. 그리고 이전 메소드는 간단한 위임으로 바꾸거나 완전히 제거하라.

Move Field (175)
필드가 자신이 정의된 클래스보다 다른 클래스에 의해서 더 많이 사용되고 있다면, 타켓 클래스에 새로운 필드를 만들고 기존 필드를 사용하고 있는 모든 부분을 변경하라.

Extract Class (179)
두 개의 클래스가 해야 할 일을 하나의 클래스가 하고 있는 경우, 새로운 클래스를 만들어서 관련 있는 필드와 메소드를 예전 클래스에서 새로운 클래스로 옮겨라.

Inline Class (184)
클래스가 하는 일이 많지 않은 경우에는, 그 클래스에 있는 모든 변수와 메소드를 다른 클래스로 옮기고 그 클래스를 제거하라.

Hide Delegate (187)
클래스가 객체의 위임 클래스를 직접 호출하고 있는 경우, 서버에 메소드를 만들어서 대리객체를 숨겨라.

Remove Middle Man (191)
클래스가 간단한 위임을 너무 많이 하고 있는 경우에는, 클라이언트가 대리객체를 직접 호출하도록 하라.

Introduce Foreign Method (194)
사용하고 있는 서버 클래스에 부가적인 메소드가 필요하지만 클래스를 수정할 수 없는 경우에는, 첫 번째 인자로 서버 클래스의 인스턴스를 받는 메소드를 클라이언트에 만들어라.

Introduce Local Extension (196)
사용하고 있는 서버 클래스에 여러 개의 메소드를 추가할 필요가 있지만 서버 클래스를 수정할 수 없는 경우, 필요한 추가 메소드를 포함하는 새로운 클래스를 만들어라. 이 확장 클래스를 원래 클래스의 서브클래스 또는 래퍼 클래스로 만들어라.

3. 데이터 구성 (Organizing Data)

Self Encapsulate Field (205)
필드에 직접 접근하고 있는 필드에 대한 결합이 이상해지면, 그 필드에 대한 get/set 메소드를 만들고 항상 이 메소드를 사용하여 필드에 접근하라.

Replace Data Value with Object (209)
추가적인 데이터나 동작을 필요로 하는 데이터 아이템이 있을 때는, 데이터 아이템을 객체로 바꾸어라.

Change Value to Reference (213)
동일한 인스턴스를 여러 개 가지고 있는 클래스가 있고 여러 개의 동일한 인스턴스를 하나의 객체로 바꾸고 싶으면, 그 객체를 참조 객체로 바꾸어라.

Change Reference to Value (217)
직고, 불변성(immutable)이고 관리하기 어려운 참조 객체가 있는 경우, 그것을 값 객체로 바꾸어라.

Replace Array with Object (220)
배열의 특정 요소가 다른 뜻을 가지고 있다면, 배열을 각각의 요소에 대한 필드를 가지는 객체로 바꿔라.

Duplicate Observed Data (224)
GUI 컨트롤에서만 사용 가능한 도메인 데이터가 있고 도메인 메소드에서 접근이 필요한 경우, 그 데이터를 도메인 객체로 복사하고 옵저버를 두어 두 데이터를 동기화하라.

Change Unidirectional Association to Bidirectional (232)
각각 서로의 기능을 필요로 하는 클래스가 있는데, 링크가 한쪽 방향으로만 되어 있는 경우, 반대 방향으로 포인터를 추가하고 수정자(modifier)가 양쪽 세트를 모두 업데이트 하게 변경하라.

Change Bidirectional Association to Unidirectional (236)
서로 링크를 가지는 두 개의 클래스에서 한 쪽이 다른 한쪽을 더 이상 필요로 하지 않을 때는 불필요한 링크를 제거하라.

Replace Magic Number with Symbolic Constant (240)
특별한 의미를 가지는 숫자 리터럴이 있으면, 상수를 만들고 의미를 잘 나타내도록 이름을 지은 다음 숫자를 상수로 바꾸어라.

Encapsulate Field (242)
public 필드가 있는 경우, 그 필드를 private으로 만들고 접근자를 제공하라.

Encapsulate Collection (244)
컬렉션(collection)을 리턴하는 메소드가 있으면, 그 메소드가 읽기 전용 뷰를 리턴하도록 만들고 add/remove 메소드를 제공하라.

Replace Record with Data Class (254)
전통적인 프로그래밍 환경에서 레코드 구조에 대한 인터페이스가 필요한 경우, 그 레코드를 위한 데이터 객체를 만들어라.

Replace Type Code with Class (255)
클래스의 동작에 영향을 미치지 않는 숫자로 된 타입 코드가 있으면 숫자를 클래스로 바꾸어라.

Replace Type Code with Subclass (261)
클래스의 동작에 영향을 미치는 변경 불가능하는 타입코드가 있다면, 타입 코드를 서브클래스로 바꾸어라.

Replace Type Code with State/Strategy (265)
클래스의 동작에 영향을 미치는 타입 코드가 있지만 서브클래싱을 할 수 없을 때는 타입 코드를 스테이트(state) 객체로 바꾸어라.

Replace Subclass with Fields (270)
상수 데이터를 리턴하는 메소드만 다른 서브클래스가 있으면, 그 메소드를 수퍼클래스의 필드로 바꾸고 서브클래스를 제거하라.

4. 조건문의 단순화

Decompos Conditional (276)
복잡한 조건문 (if-then-else)이 있는 경우, 조건 then 부분 그리고 else 부분에서 메소드를 추출하라.

Consolidate Conditional Expression (278)
같은 결과를 초래하는 일련의 조건 테스트가 있는 경우, 그것을 하나의 조건식으로 결합하여 뽑아라.

Consolidate Duplicate Conditional Fragments (281)
동일한 코드 조각이 조건문의 모든 분기 안에 있는 경우, 동일한 코드를 조건문 밖으로 옮겨라.

Remove Control Flag (283)
일련의 boolean 식에서 컨트롤 플래그 역할을하는 변수가 있는 경우, break 또는 return을 대신 사용하라.

Replace Nested Conditional with Guard Clauses (288)
메소드가 정상적인 실행 경로를 불명확하게 하는 조건 동작을 가지고 있는 경우, 모든 특별한 경우에 대해서 보호절을 사용하라.

Replace Conditional with Polymorphism (293)
객체의 타입에 따라 다른 동작을 선택하는 조건문을 가지고 있는 경우, 조건문의 각 부분을 서브클래스에 있는 오버라이딩 메소드로 옮겨라. 그리고 원래 메소드를 abstract로 만들어라.

Introduce Null Object (298)
null 체크를 반복적으로 하고 있다면, null 값을 null 객체로 대체하라.

Introduce Assertion (306)
코드의 한 부분이 프로그램의 상태에 대하여 어떤 것을 가정하고 있으면, assertion을 써서 가정을 명시되게 만들어라.

5. 메소드 호출의 단순화

Rename Method (313)
메소드의 이름이 그 목적을 드러내지 못하고 있다면, 메소드의 이름을 바꿔라.

Add Parameter (316)
어떤 메소드가 그 메소드를 호출하는 부분에서 더 많은 정보를 필요로 한다면, 이 정보를 넘길 수 있는 객체에 대한 파라미터를 추가하라.

Remove Parameter (318)
파라미터가 메소드 몸체에서 더 이상 사용되지 않는다면, 그 파라미터를 제거하라.

Separate Query from Modifier (320)
값을 리턴할 뿐만 아니라 객체의 상태도 변경하는 메소드를 가지고 있는 경우, 두 개의 메소드를 만들어서 하나는 값을 리턴하는 역할을 하고, 하나는 객체의 상태를 변경하는 역할을 하게 하라.

Parameterize Method (325)
몇몇 메소드가 메소드 몸체에 다른 값을 포함하고 있는 것을 제외하고는 비슷한 일을 하고 있다면, 다른 값을 파라미터로 넘겨 받는 하나의 메소드를 만들어라.

Replace Parameter with Explicit Methods (327)
파라미터의 값에 따라서 다른 코드를 실행하는 메소드가 있다면, 각각의 파라미터 값에 대한 별도의 메소드를 만들어라.

Preserve Whole Object (331)
어떤 객체에서 여러 개의 값을 얻은 다음 메소드를 호출하면서 파라미터로 넘기고 있다면, 대신 그 객체를 파라미터로 넘겨라.

Replace Parameter with Method (335)
객체가 메소드를 호출한 다음, 결과를 다른 메소드에 대한 파라미터로 넘기고 있다. 수신자 또한 이 메소드를 호출할 수 있다면 그 파라미터를 제거하고 수신자가 그 메소드를 호출하도록 하라.

Introduce Parameter Object (339)
자연스럽게 몰려다니는 파라미터 그룹을 가지고 있다면, 그것들을 객체로 바꾸어라.

Remove Setting Method (344)
어떤 필드가 객체 생성시에 값이 정해지고 그 이후에는 변경되지 않아야 한다면, 그 필드 값을 설정하는 모든 메소드를 제거하라.

Hide Method (348)
메소드가 다른 클래스에서 사용되지 않는다면, 그 메소드를 private로 만들어라.

Replace Constructor with Factory Method (350)
객체를 생성할 때 단순히 생성하는 것 이외에 다른 작업도 하고 있다면, 생성자를 팩토리 메소드로 대체하라.

Encapsulate Downcast (355)
메소드가 그 호출부에서 다운캐스트 될 필요가 있는 객체를 리턴하고 있다면 다운캐스트 하는 것을 메소드 안으로 옮겨라.

Replace Error Code with Exception (357)
메소드가 에러를 나타내는 특별한 코드를 가지고 있다면, 대신 예외를 던져라.

Replace Exception with Test (363)
호출부에서 먼저 검사할 수 있는 조건에 대해 예외를 던지고 있다면, 호출부가 먼저 검사하도록 바꿔라.

6. 일반화 다루기

Pull Up Field (368)
두 서브클래스가 동일한 필드를 가지고 있다면, 그 필드를 수퍼클래스로 옮겨라.

Pull Up Method (370)
동일한 일을 하는 메소드를 여러 서브클래스에서 가지고 있다면, 이 메소드를 수퍼클래스로 옮겨라.

Pull Up Constructor Body (373)
서브크래스들이 대부분 동일한 몸체를 가진 생성자를 가지고 있다면, 수퍼클래스에 생성자를 만들고 서브클래스 메소드에서 이것을 호출하라.

Push Down Method (376)
수퍼클래스에 있는 동작이 서브클래스 중 일부에만 관련되어 있다면, 그 동작을 관련된 서브클래스로 옮겨라.

Push Down Field (377)
어떤 필드가 일부 서브클래스에 의해서만 사용되고 있다면, 그 필드를 관련된 서브클래스로 옮겨라.

Extract Subclass (378)
어떤 클래스가 일부 인스턴스에 의해서만 사용되는 기능을 가지고 있다면, 기능의 부분집합을 담당하는 서브클래스를 만들어라.

Extract Superclass (384)
비슷한 메소드와 필드를 가진 두 개의 클래스가 있다면, 수퍼클래스를 만들어서 공통된 메소드와 필드를 수퍼클래스로 옮겨라.

Extract Interface (389)
여러 클라이언트가 한 클래스 인터페이스와 동일한 부분 집합을 사용하고 있거나, 두 클래스가 공통된 인터페이스를 가지는 부분이 있다면, 그 부분 집합을 인터페이스로 뽑아내라.

Collapse Hierarchy (392)
수퍼클래스와 서브클래스가 별로 다르지 않다면, 그것들을 하나로 합쳐라.

Form Template Method (393)
각각의 서브클래스에 동일한 순서로 비슷한 단계를 행하지만 단계가 완전히 같지는 않은 두 메소드가 있다면, 그 단계를 동일한 시그니처를 가진 메소드로 만들어라. 이렇게 하면 원래의 두 메소드는 서로 같아지므로, 수퍼클래스로 올릴 수 있다.

Replace Inheritance with Delegation (401)
서브클래스가 수퍼클래스 인터페이스의 일부분만 사용하거나 또는 데이터를 상속 받고 싶지 않은 경우, 수퍼클래스를 위한 필드를 만들고 메소드들이 수퍼클래스에 위임하도록 변경한 후 상속 관계를 제거한다.

Replace Delegation with Inheritance (404)
위임을 사용하고 있는데 전체 인터페이스에 대해 간단한 위임을 자주 작성하고 있다면, 위임하는 클래스를 대리객체의 서브클래스로 만들어라.




Trackback 0 And Comment 0

자주 리펙토링을 하라.(2)

|



리펙토링을 하려면 소스 코드 속의 나쁜 냄새를 맡을 수 있어야 한다고 합니다.

"리펙토링"이란 책에서 켄트 벡(Kent Beck)과 마틴 파울러(Martin Fowler)가 이야기한 코드 속의 나쁜 냄새에 대해 정리해 보려고 합니다.

사용자 삽입 이미지


중복된 코드 (Duplicated Code)
- 동일한 소스가 여기 저기 사용된다면 반드시 리펙토링을 해야 한다고 합니다.
Extract Method (136), Extract Class (179), Pull Up Method (370), Form template Method (393)

긴 메소드 (Long Method)
- C 프로그래밍부터 시작해서인지 절차적 프로그래밍에 익숙한 경우, 하나의 메소드에서 모든 일을 처리하는 경우가 종종 있습니다. 긴 메소드는 쪼개야 한다고 하네요~
Extract Method (136), Replace Temp with Query (147), Replace method with Method Object (163), Decompose Conditional (276)

거대한 클래스 (Large Class)
- 클래스가 너무 많은 일을 하면 변수도 많아지고, 중복된 코드도 많아질 가능성이 높다고 합니다.
Extract Class (179), Extract Subclass (378), Extract Interface (389), Replace Data Value with Object (209)

긴 파라미터 리스트 (Long Parameter List)
- 메소드에 전달되는 파라미터가 길면 소스를 이해하는 것이 어렵기 때문에 수정하는 것이 낫다고 합니다.
Replace Parameter with Method (335), Introduce Parameter Object (339), Preserve Whole Object (331)

확산적 변경 (Divergent Change)
- 말이 좀 어려운데요..  A라는 클래스를 "가" 이유 때문에  3개의 메소드를 수정해야 하고, 또 "나" 이유 때문에 4개의 메소드를 수정해야 한다면.. 차라리 "A가", "A나"와 같이 두개의 객체로 만드는 것이 바람직하다는 것인데요.. 대략적으로는 알겠는데 정말 확 와닿지는 않네요..
Extract Class (179)

산타총 수술 (Shotgun Sugery)
- 역시 어려운 말입니다. -.- 자주 수정하는 부분인데.. 한번 수정할 때마다 여러개의 클래스를 수정해야 한다면 이를 하나의 클래스만 수정하도록 변경해야 한다는 겁니다. 요건 가끔 있을 것 같네요..
Move Method (170), Move Field (175), Inline Class (184)

기능에 대한 욕심 (Feature Envy)
- 메소드가 자신이 속한 클래스보다 다른 클래스를 더 많이 활용하고 있다면, 옮겨야 겠죠..
Move Method (170), Move Field (175), Extract Method (136)

데이터 덩어리 (Data Clump)
- 한 클래스와 관련없는 여려 데이터들이 모여있는 경우입니다. 각각의 역할에 맞는 여러개의 객체로 쪼개야 한다고 하네요..
Extract Class (179), Introduce Parameter Object (339), Preserve Whole Object (331)

기본 타입에 대한 강박관념 (Primitive Obsession)
- 기본 타입만을 고집하지 말고 Money 클래스, Range 클래스, 전화번호 클래스, 우편번호 클래스등 특정한 작업을 위한 작은 객체를 충분히 활용하라고 합니다.
Replace Data Value with Object (209), Extract Class (179), Introduce Parameter Object (339), Replace Array with Object (220), Replace Type Code with Class (255), Replace Type Code with Subclasses (261), Replace Type Code with State/Strategy (265)

Switch 문 (Switch Statements)
- Switch 문은 객체지향 코드에서는 다형성을 이용해 수정해 주어야 한다고 합니다. 기본적으로 Switch문이 중복성을 가지고 있기 때문이라고 하네요~
Replace Conditional with Polymorphism (293), Replace type with Subclasses (261), Replace Type Code with State/Strategy (265), Replace Parameter with Explicit Method (327), Introduce Null Object (298)

게으른 클래스 (Lazy Class)
- 클래스가 충분한 일을 하지 않을 경우, 제거해야 한다는 겁니다.
Inline Class (184), Collapse Hierarchy (392)

추측성 일반화 (Speculative Generality)
- 앞으로 필요할 것 같아서 미리 추가한 기능과 관련된 코드중 실제로 사용되지 않는 것은 삭제하라는 거네요
Collapse Hierarchy (392), Inline Class (184), Remove Parameter (318), Rename Method (313)

임시 필드 (Temporary Field)
- 객체 안의 인스턴스 변수가 특정 상황에서만 사용된다면, 이해하기 어렵게 되므로 변경해야 한다고 하네요.
Extract Class (179), Introduce Null Object (298)

메시지 체인 (Message Chains)
- 어떤 객체를 사용하기 위해 다른 객체에 물어보고, 다른 객체는 다시 또 다른 객체에 물어보고, 그 객체는 다시 다른 객체에 물어보고.. 이런 경우가 메시지 체인이라고 하네요~~
Hide Delegate (187)

미들 맨 (Middle Man)
- 클래스 메소드의 대부분이 다른 클래스로 위임하고 있다면.. 지나친 캡슐화를 사용한고 있다는 것인데요.. 리펙토링을 적용해야 한다고 하네요~
Remove Middle Man (191), Inline Method (144), Replace Delegation with Inheritance (404)

부적절한 친밀 (Inappropriate Intimacy)
- 지나치게 친밀한 클래스는 서로 갈라 놓아야 한다고 하네요..
Move Method (170), Move Field (175), Change Bidirectional Association to Unidirectional (236), Replace Inheritance with Delegation (401), Hide Delegate (187)

다른 인터페이스를 가진 대체 클래스 (Alternative Classes with Different Interface)
- 같은 작업을 하지만 다른 시그너처를 가진 메소드에 대해서 리펙토링 하라는 거네요..
Rename Method (313), Move Method (170)

불완전한 라이브러리 클래스 (Incomplete Library Class)
- 기존의 라이브러리 클래스가 가지고 있었으면 하는 메소드가 있다면 리펙토링을 통해 보완하라는 겁니다.
Introduce Foreign Method (194), Introduce Local Extension (196)

데이터 클래스 (Data Class)
- get / set 메소드만 가진 클래스.. 실제로 많이 만드는 데요~ 이런 경우 적절한 리펙토링을 하라는 거네요~
Move Method (170), Encapsulate Field (242), Encapsulate Collection (244)

거부된 유산 (Refused Bequest)
- 상속구조가 잘못된 경우, 새로운 형제 클래스를 만들고 리펙토링해야 한다는 이야기 입니다.
Replace Inheritance with Delegation (401)

주석 (Comments)
- 주석을 써야 할 것 같다면 먼저 코드를 리펙토링 하여 주석이 불필요하도록 하라는 거네요..
Extract Method (136), Introduce Assertion (306)

리펙토링은 최적화의 개념이 아니라.. 소스 코드를 이해하기 쉽게 만드는 겁니다.
소스 코드 속의 나쁜 냄새를 잘 파악할 수 있도록 위의 내용을 참고하시기 바랍니다.




Trackback 0 And Comment 1

자주 리펙토링을 하라.(1)

|



프로그래머들은 한번쯤 리펙토링이라는 것을 들어봤을 겁니다.
리펙토링이 좋다는 것은 익히 들어 알겠는데 실제로 못하는 경우가 대부분입니다.

왜 그럴까요?

우선, 리펙토링이 무엇이고 어떻게 하는 것인지 모르기 때문인 것 같습니다.
솔직히 저도 리펙토링 관련 책을 이번에 읽어보기는 했지만,
아직도 어떤 경우에 리펙토링을 해야 하는지 느낌이 확 오지는 않습니다. -.-

A->B로 변경하는 것이 설명되어 있으면, 바로 B->A로 바꾸는 것도 설명되어 있습니다.
즉, 경우에 따라 적용하는 리펙토링이 다르다는 것인데.. 이건 경험이 필요한 것 같습니다.~
끊임없이 생각해보고 변경하다보면 어떤 것이 올바른 리펙토링인지 알수 있지 않을까 합니다.

다음으로는 리펙토링을 하고 있으면, 윗분들은  아무것도 하지 않고 있다고 생각하는 경우가 많을 것 같습니다.
열심히 뭔가 코드를 고치고는 있는데, 프로그램 결과물이 바뀐게 없으니까요..
리펙토링은 기능개선이나 디버깅과 달리 프로그램을 현재 상태 그대로 두고 소스코드만 이해하기 쉽게 바꾸는 것이니까요..

하지만 이 작업의 중요성을 충분히 설명해 주어야 한다고 생각합니다.
프로젝트가 대규모가 될수록.. 추후 유지보수를 위해서도 리펙토링은 반드시 필요하거든요.

방법론에 따른 산출물이 있지 않느냐? 하고 반문할 수도 있지만..
글쎄요~~ 산출물은 끊임없이 바뀌는 프로그램을 모두 반영할 수 있을지 솔직히 의문이거든요
특히, 산출물에 기반하는 개발이 아닌, 개발후 형식적으로 만드는 산출물은 더욱 문제겠지요..
리펙토링을 통해 소스 자체가 훌륭한 산출물이 된다면 더할 나위 없지 않을까 합니다. ^^

사용자 삽입 이미지



마틴파울러(Martin Fowler)의 다음 이야기가 떠오르네요..
"컴퓨터가 이해할 수 있는 코드는 어느 바보나 다 짤 수 있다. 좋은 프로그래머는 사람이 이해할 수 있는 코드를 짠다."
그렇다면, 리펙토링은 언제 해야 할까요?
자주.. 생각날 때마다 하는 것이 따로 일정을 잡아서 하는 것보다는 수월하다고 하네요..

그리고 리펙토링을 하려면 잘못됐을 때 소스를 이전 버전을 바꿀 수 있는 버전관리와..
현재 프로그램 전체를 테스트할 수 있는 테스트코드 또한 중요한 요소라고 합니다.

리펙토링을 통해서 잘 디자인된 소스코드를 만드시기 바랍니다.




Trackback 0 And Comment 0

테스트 코드.. 우선 개발할 것인가?

|



요즘 테스트 코드와 관련해서...

테스트 코드를 먼저 만들고 난 후, 코딩을 진행하는 것이 좋다...
또는 프로그래밍 코딩을 하면, 테스트 코드를 만들어 확인해야 한다..
리펙토링을 하기 전에는 반드시 테스트 코드가 있어야 한다..

라는 이야기를 많이 합니다.
 
테스트 코드라는 것이 매우 중요한 개념이라는 것은 많이 들어서 알 것 같습니다.
그런데.. 실천이 매우 어렵다는 것을 한번 느낀 적이 있어 글을 써봅니다.
 
최근 프로젝트에서 JUnit이라는 테스트 프레임워크와
Ant 툴을 이용해서 프로젝트에서 테스트 프로그램을 구성해 보았습니다.

흔히 말하듯 빌드 한방에 테스트가 완료되구요..
테스트 전후의 데이터도 변화가 없게 만들고...
나름 머리써가면서 잘 만들어 놨었죠~~

하지만, 테스트 구현에 있어 약간의 한계가 있었는데요..

첫째로, 테스트 코드를 만든 사람과 실제 프로그램 소스를 구현하는 사람이 달랐다는 점입니다.
팀원간의 소스코드에 대한 이해도 높인다는 (실은 프로젝트 관리자로서 개발자들의 코드를 살펴본다는 의미가 더 강했죠.. -.-) 명목하에 그렇게 구성했었죠..
그러다 보니.. 소스 코드가 명세 변경에 바뀌어 갈 때마다 테스트 코드도 업버전 되어야 하는데. 그렇게 되지 못했다는 겁니다.
결국 나중에는 테스트 코드는 쓰레기 코드가 되어 버려지게 되었죠.. -.-
(이 점이 아쉬웠는데요... 테스트 코드를 계속 발달시켜야 하는데.. 프로젝트 중간에 그러기가 어려웠거든요.)

둘째로, 테스트 프로그램이 모든 소스 코드를 커버해 주면 좋겠지만...
웹에서 받아들이는 부분은 일단 커버를 못해줬다는 점입니다.
Junit에 살펴보면 request, response를 가상으로 제어하는 부분이 있기는 하지만,
거기까지 적용하기는 복잡해서.. 내부 프레임워크에서 비즈니스 로직을 처리하는 부분부터만 테스트 코드를 적용한 거죠..
(이 부분은 이렇게 하는게 오히려 단순해 지기 때문에 테스트 구현에 도움이 되기는 하지만, 전체 프로젝트를 커버할 수없다는 단점도 있는 것 같더라구요.. )

어쨌든 처음으로 테스트 코드를 만들어 프로젝트에 넣어보았지만, 일단 성공하지는 못한 것 같습니다.
다음에는 테스트 코드를 먼저 만들고 코딩을 진행하는 방법도 한번 시도해 보려고 합니다.

혹시 이 부분에 대해서 좋은 경험 가진 분들의 댓글 부탁드립니다.
그럼.. 좋은 일요일 저녁 되세요~~




Trackback 0 And Comment 0
prev | 1 | next