2008년 11월 26일 수요일

객체지향... 필요한가?

써니님의 "절차지향도 훌륭한데, 왜 객체지향인가?"라는 글을 읽고 객체지향에 대한 견해를 적어봅니다.


먼저 글을 읽고 계신 분이 C언어로 프로그래밍을 하시나요?
그러면 질문이 있습니다.

"static 함수를 사용하시나요? 또 static 함수의 용도를 아시나요?" "static 변수가 아닙니다."
사용하고 계시고 정확한 용도를 알고 계시면 C언어로도 객체지향 프로그래밍을 하고 계시는 것일 겁니다.

이 질문에 갸우뚱하시는 분이 계시나요?

그럼 이야기를 시작해보죠.

여기서 이슈를 다음 두 가지로 나눠야 할 것 같습니다.
  • 객체지향 프로그래밍
  • 객체지향 프로그래밍 언어사용
첫째, 객체지향 프로그래밍은 당연히 필요하다고 생각합니다. 

우선 몇 만 라인 이하의 소규모 소프트웨어를 개발할 때와 혼자서 소프트웨어를 개발할 때는 좀 논외로 하고 싶습니다. 이런 경우의 예를 들기 시작하면 사실 어떻게 해도 불편할 것도 없고 안되는 것도 없습니다.

적어도 수십만 라인의 이상의 코드를 다루고, 5,6명 또는 수십, 수백 명의 개발자들이 같이 일을 할 경우를 기준으로 생각해야 할 것 같습니다. 지금은 혼자 소규모의 소프트웨어를 개발하고 있어도 언젠가는 이런 규모의 소프트웨어를 개발하는데 참여하겠죠. 따라서 혼자서 개발을 하고 있어도 "나랑은 상관없는 얘기다"는 아닙니다.

프로그래밍에 객체지향 개념 도입된지는 매우 오래 되었습니다. 객체지향 프로그래밍 언어가 나오기 훨씬 이전부터 개발자들은 객체 지향적으로 개발을 하고 있었습니다. 그렇지 않고서는 너무 복잡해서 개발을 할 수가 없었거든요. 그 뒤로 이러한 요구를 만족시키기 위해서 객체지향 프로그래밍을 잘 할 수 있는 언어들이 나오기 시작한 거죠. 

객체지향의 기본 컨셉인 추상화, 캐슐화, 정보의 은닉 이런 것들은 오래 전부터 사용을 해왔죠.
그렇지 않고 절차적이고 구조적인 프로그래밍을 하게 되면 시스템의 규모가 커질 수록 그 복잡도가 너무 커져서 감당할 수가 없었죠.

그래서 개발을 할 때 시스템의 각 컴포넌트는 잘 나눠서 각 컴포넌트끼리는 간결한 인터페이스를 정의해서 해당 인터페이스만을 가지고 통신을 하도록 하고 각 개발자들은 자신이 담당함 컴포넌트만 개발할 수 있도록 했죠. 이러한 개념을 데이터와 메쏘드를 엮어서 객체지향 이론을 점점 발전시켜 왔습니다. 

C언어에서도 static 함수를 사용하면 해당 파일의 내부에서만 호출이 가능하고 외부 다른 파일에서는 호출할 수 없습니다. 즉 private 함수와 같은 효과를 발휘합니다. 따라서 public함수가 아닌 함수는 모두 static으로 정의를 해야 합니다. 그렇지 않으면 함수가 바뀌게 되었을 때 수천, 수만 개의 파일 중에서 누가 그 함수를 사용하고 있는지 정확하게 추적해서 문제없이 수정하는 것은 너무나 어려워 집니다. static함수는 해당 파일 내에서만 검토를 하면 되기 때문에 문제 없죠. 혹시 지금 C언어로 작성된 소스코드가 있으면 함수에 static이 정의 되어 있는지 확인해보세요.

둘째, 객체지향 프로그래밍 언어도 당연히 유용합니다.

C언어로도 객체지향 개념을 적용할 수 있지만, 한계가 있죠. 제대로 된 객체지향 프로그래밍을 하려면 객체지향 프로그래밍 언어가 필요합니다. 하지만 C언어로 개발을 하는 것에 대해서도 전혀 부정적인 의식은 없습니다.

주변에서 보면 언어만 C++을 사용하고 코드 내부를 뜯어보면 전혀 객체지향적이지 않는 소스코드를 많이 봅니다. 이런 경우보다는 C언어로 잘 작성하는 것이 더 낳죠.

물론 C++이 가장 훌륭한 객체지향언어라고 할 수는 없습니다. 그래서 객체지향 프로그래밍을 하기 위해서는 어떤 프로그래밍언어를 사용해야 한다고 주장하고 싶지는 않습니다.

한때 객체지향 개발방법론이 대두되어서 이전의 모든 문제를 다 해결해 줄 것처럼 떠들었지만, 이는 결국 언어를 무엇을 사용하고 방법론을 뭘 쓰느냐의 문제는 아니고 개발자들의 역량에 달린 문제 같습니다.

결론은 이렇습니다. 
"객체지향이 유용하기는 하나 무슨 언어를 쓰냐보다는 개발자의 객체지향 개발 역량이 더 중요하다."

객체 지향이라는 것이 꼭 알아야 하는 것이지만 툴에 목을 메지는 맙시다.


절차지향도 훌륭한데, 왜 객체지향인가? 
by 써니

구조적 프로그래밍 혹은 절차지향적 프로그래밍이라고도 말하는 C언어를 학습하시거나, 현장에서 C언어를 이용해서 개발하시는 분들과 대화를 나누다 보면 굳이 객체와 클래스라는 생소하고 어색한(?) 개념을 도입해서 개발해야 하는지 그 필요성을 잘 느끼지 못한다고 하십니다. 저 또한 베이식 - 베이직 보다 베이식이 정확한 발음이더군요 - 그리고, C언어를 먼저 학습한 사람이기 때문에 어느 정도 공감하고 있습니다.

단순한 프로그램을 개발하건, 복잡한 프로그램을 개발하건 구조적 프로그래밍이건 객체지향 프로그래밍 기법을 사용하건 어떠한 문제를 풀던 간에 눈에 보이는 결과 자체로는 차이점을 발견할 수 없습니다. 그러니까, C언어로 윈도우 어플리케이션을 만들어도 잘 동작하고, C#으로 만들어도 잘 동작합니다. 여전히 대부분의 운영체제는 C언어로 개발되고 있고, 전세계에서 운영되고 있는 수많은 제품들과 정보시스템들이 여전히 C언어로 구현 및 유지보수 되고 있습니다. 여전히 수많은 금융기관에서는 코볼로 작성된 프로그램들을 사용하고 있고, 게다가 아주 성공적으로 운영되고 있습니다.



2008년 11월 24일 월요일

코더(Coder)의 비애



블로그에서 설계에 대한 몇몇 글들을 의견을 적어보려고 합니다. 


안녕하세요. Ray입니다.
써니님이 지금 하시는 일을 코딩이라고 만 얘기할 수는 없는것 같습니다. 분석, 설계도 다 하고 계시는데, 문서화가 안되어 있거나 부족할 수는 있어도 분석, 설계는 하고 있는 거죠.
적은 인원이나 소규모 프로젝트에서는 설계가 별로 이슈가 되고 있지 않습니다.
이런 상황에서 인도에 외주를 줄만큼 설계를 하는것도 낭비죠.

하지만, 내가 설계를 해서 다른 사람이 내 설계서를 보고 약간만 물어보면서 구현(코딩)을 할 수 있느냐를 따져보면 설계 이슈는 전면으로 부각됩니다.

실제로 제대로 설계를 해서 산출물을 만들어 외부에 코딩(구현) 외주를 줄 수 있는 사람은 많지 않습니다.
하지만 이런 구현 외주는 미국과 인도에서는 흔한 일이죠. 물론 설계를 가르쳐 주는 곳도 없어서 배울 수는 있지만, 애초에 이러한 환경에서 같이 일을 했으면 잘 작성된 설계서를 보고 구현도 하고 아키텍쳐 설계회의에도 참석하고 많이 배우죠.

우리의 예를 보면 소규모 기업에서 좋은 소프트웨어를 히트쳐서 회사가 갑자기 켜지고 2,3명이서 개발하던 개발팀이 수십명으로 늘어나면서 제품은 복잡해지고 켜졌는데, 제품은 이전만 못한 경우를 많이 봤습니다.
여러 다른 이유가 있지만, 설계 방법에 대한 이슈도 그 문제에 한몫을 합니다.

밑에 Cavin님이 말씀하신 것 처럼 설계 컨설턴트는 있을 수 없습니다. 제 직업이 소프트웨어 컨설턴트이지만, 설계자체를 컨설팅 해줄 수는 없습니다.
또 설계를 가르쳐주는 것도 거의 불가능합니다.
설계의 기본 컨셉, 방법, 툴 사용법 등을 가르쳐 줄 수는 있습니다.
하지만 이것들이 설계를 할 수 있게 해주지 않습니다.
그런 것들을 모두 다 알고도 오랜 경험이 또 필요하고, 문서화를 할 수 있는 실력도 필요하죠. 알고 있는 기술 분야도 워낙 다양해서 최고의 설계 컨설턴트가 도와준다는 것도 말이 안되는 얘기고 일부 기술이나 아키텍쳐에 대해서 도움을 받는 정도 이죠.

여기서 "설계는 뭐다"라고 얘기할 것은 하나도 없습니다.
그래도 이렇게 끝나는 글이 되면 너무 썰렁하니 설계의 시작과 끝 정도 정의하고 그 속은 워낙 다양하니 차차 여러 가지 의견을 글로 남겨보도록 하겠습니다.

설계의 시작은 우선 인터페이스을 찾아내는 것입니다. 그래서 인터페이스와 컴포넌트들을 구분하면서 시작이 됩니다. 이 개념은 OOP에서 출발한 것도 아니고 가장 전통적인 방법입니다. 소프트웨어의 분야는 수없이 바뀌어 왔지만설계의 원리는 크게 변하지 않았습니다코볼로 만들던자바로 만들던 소프트웨어를 만드는 철학은 기본적으로 많이 다르지 않습다설계의 기본은 시스템의 단위를 좀 더 작은 단위로 분할해 가면서 아키텍처를 설계하는 것입니다설계는 시스템을 잘게 나눠서 컴포넌트와 모듈을 정의하고 그 인터페이스를 정하는 작업입니다수많은 설계 방법들이 있지만 그 기본은 바뀌지 않았습니다카네기-멜론 소프트웨어 엔지니어링 인스트튜트에서 주창한ADD(Attribute-Driven Design, 속성 주도 설계방법이든다른 여러 아키텍처 수립 방법론들은 결국 이 방법을 체계화 한 것입니다.

UML과 같은 도구는 설계를 하는데 일부 도움은 될 수 있지만 설계에 꼭 필요한 것은 아닙니다설계한 결과를 적는 하나의 도구일 뿐입니다설계라는 작업은 소프트웨어 개발에 있어서 가장 자유도가 높고 창의성이 요구되는 작업입니다설계 기간은 선임 개발자들의 실력이 가장 많이 드러날 수 있는 기회이기도 합니다소소의 사람만이 쓸 수 있는 능력을 가지고 있는 SRS와는 달리 설계는 모든 선임개발자가 가져야 하는 필수적인 역량입니다설계에 대해서 너무 많은 제약을 가한다면좋은 설계가 나오기는 어려울 것입니다

그럼 설계의 끝은 어디일까요. 적어도 어느 정도까지 설계가 되어야 구현이 진행될 수 있을 까요?
설계가 끝나면 빌드(Build)가 시작되는 것이 기본 원칙입니다.
Class나 수많은 Public함수들의 Prototype이 모두 정의 되어 있고, Build Script까지 완성이 되어서 Daily Build가 시작됩니다. 그러면 Coder는 함수들의 내용과 Sub-function을 만들게 됩니다. Coder에게 함수와 Class를 어떻게 작성해야 하는지 설계서를 작성하는 것은 여기서 설명하기는 어렵겠죠.
여기서 말하려고 하는 것은 이정도까지 설계 단계에서 진행이 되지 않으면 Coder에게 일을 시키는 것은 사실 상 어렵습니다. 
설계를 중점적으로 담당하는 선임 엔지니어들은 지루한 코딩 작업은 가능하면 하지 않을려고 하죠. 설계가 훨씬 재미고 창의적인 작업이기 때문이죠. 그래서 코딩 작업은 신입사원이나 초급 개발자를 시키는 거죠.

이글을 보고 개발자들이 설계를 하는데 일말의 도움이 될 것이라고 생각하지 않습니다.
그냥 주변에서 돌아다는 Software Engineer, Archict, Coder등의 용어들에 너무 구애 받지 말고 자신의 일을 했으면 하는 바랍입니다.

물론 설계 능력 향상을 위한 노력은 매우 중요하죠. 수많은 책을 봤다는 분도 계시는데, 분명 도움이 될 것입니다. 그동안 쌓아온 많은 경험도 필수고요.

앞으로 계속 이에 대한 글들을 써보도록 하겠습니다.
위 글중의 일부는 제 책(소프트웨어 개발의 모든것)에서 인용했습니다.



각 블로그들의 인용문입니다.

저는 여전히 코더(coder)입니다~ by 써니
 하지만, 분명하게 이야기 하고 싶은 것은 제가 매일 하고 있는 일은 코딩이지 설계가 아니라는 것입니다. 그 근거로서 말씀드리지요. 저희 회사에 개발자가 저 혼자 뿐입니다. 누구에게 지시를 내리고 할 위치가 아니라는 것입니다. 또한 코더와 아키텍트, 고수와 하수를 나누고 그들 사이에 편가르기를 시도하려고 하지도 않습니다. 편가르기를 하려면 어느 한 편에 서야만 하는데 저는 양쪽 위치에 다 서 있는 입장입니다. 개발을 하면서 프로젝트 매니저의 역할을 맡은 적도 몇번 있지만 그런 상황에서도 한번도 코딩을 손에서 놓은 적이 없습니다. 그러니까 지금도 코딩을 할 수 있는 것이죠.
Software Design은 결코 쉬운 일이 아닙니다. 10년 20년을 개발했다고 해도, UML을 철저히 공부했다고 해도 여전히 어려운 것이 소프트웨어 디자인입니다. 실용주의 프로그래머, GoF의 디자인 패턴, Head First 시리즈, 아무도 가르쳐주지 않는 프로그래밍 설계 기법, XP 방법론, 리팩토링, Test Driven Development... 온갖 좋은 책을 다 읽어도 구구단을 쉽게 설계하는 법은 아무 책에도 나와 있지 않습니다. 즉, 현실 문제는 책에서 다루는 이상과는 달리 그 변화와 종류가 너무나 방대하기 때문에 정답을 얻기가 어려운 것입니다. 앞서 언급한 기술들과 그 기술들을 저술한 분들은 분명히 손꼽히는 대가인데도 말입니다.
  
꼭 그래야만 하는 이유
 사실 Coder를 거치지 않는 Programmer, Architect는 존재하지 않는다고 봐도 무방합니다. 기본적인 Code에 대한 이해를 가지지 않고 그 일을 한다는 건(현실에서 ‘종종’ 있는 일입니다만..) 배재하고 이야기 해보겠습니다. Coder와 Programmer, Architect의 차이는 뭘까요? 남들 모르는 몇가지 알고리즘을 더 아는 것? 남들 모르는 지식 몇가지를 더 알고 있는 것? 그런 사소한 차이는 같은 Coder,Programmer 사이에 비일비재한 일입니다. 그런 것들로 Coder, Programmer, Architect 는 구분되지 않습니다. 그럼 (나름)구분 할 방법은 무엇일까요? 아니 사람들은 대체!! 어떤 기준으로 너는 Coder, 나는 Programmer! 이런 이야기를 하는 걸까요? 사실 저도 잘 모르겠습니다만… 위의 컨설팅 과정 중에 나온 여러가지 이야기들과 그간의 사람들과 대화를 나누며 격어본 경험들에 비추어 (여러가지로 표현가능하지만) 문제 인식의 차이라고 표현하고 싶습니다.
  
납득할 수 있는 설계를 어디서 배울 수 있을까?
 업계에 설계전문 컨설턴트란 롤은 들어보지 못했다. 예로, 최근 설계에 대한 이슈를 안고 있는 대형 프로젝트가 두 개가 있는데.. 이례적으로 아키텍처가 상세하게 분화되서 분야별 아키텍트가 컨설턴트로 투입되었고, 솔루션 기반의 implementation consulting이라는 롤도 별도로 존재하고 투입되었다. 하지만 이런 환경임에도 설계 컨설팅은 없다. 별도 롤로 구분하지 않고 기술관련된 전반적인 문제들을 아키텍처 팀이나 그룹에 위임을 하는게 일반적인 프로젝트들의 전략이기 때문. 실제로 대형 프로젝트 아키텍처 팀이나 그룹은 그러한 이유로 팀사이즈가 꽤 큰 편. 
 그렇다면 프로젝트에서 누가 설계를 가이드해야 할까? 설계는 다분히 전략에 대한 내용들도 많고, 영향을 미치거나 받는 부분이 많다. 시간적으로도 일정 'phase'에 국한되지 않고, 특정 'discipine'에 한정되지도 않는다. 전략들을 설계로 모으고 드라이브 하는 사람은 방법론과 아키텍트. 아키텍처 적용이전은 방법론, 적용되는 시점부터는 아키텍트. 따라서 방법론, 아키텍트 둘의 긴밀한 협조로 설계를 일궈나가야 한다. 그렇지만, 200억, 500억대 프로젝트에서 아키텍트, 방법론 둘 다 빵꾸내기도 하는 이 현실은 완전 시궁창이지만서도..(먼산~) 
  
 꼭 그래야만 하는 걸까요?
너희 같은 하수는 평생 그렇게 코딩만 해라 나는 아키텍트의 길로 가련다... 하는 분들도 있을것 같네요. 예, 저는 하수 입니다. 당장 MFC나 위저드의 도움 없이는 Window도 제대로 생성하지 못하는 바보일 뿐이죠. 당장 개발해야 할 당면 과제는 COM 이나 CORBA 컴포넌트 제작이 아닌 제공되는 컴포넌트와 API를 이용한 어플리케이션 제작 입니다. 그렇다고 해서 삽질이나 하는 바보 개발자로 취급 받아도 좋은 걸까요? 훌륭하신 여러분들이 그렇게 무시하는 코더들은 그야말로 코드를 생산하는 위자드 보다도 못한 그런 사람들 일까요? 저는 잘 모르겠습니다. 그렇게 자기가 정한 기준에 맞지 않는 다른 사람들을 무시하는 풍토가 IT 업종의 3D화를 이뤄냈다고는 생각해본적 없으신가요?

The 12 Best Questions for Team Members

제가 구독하는 블로그에서 유용한 정보가 있어서 소개를 할까합니다.
이 설문은 First, Break All the Rules: What the World's Greatest Managers Do Differently (Marcus Buckingham and Curt Coffman)에 소개가 되어 있습니다.

아래 12가지 설문을 통해서 직업의 만족도, 상사와의 관계, 자기계발등 조직의 몰입도를 측정할 수 있습니다.
IT나 Software 조직에 국한 된 것이 아니라, 모든 회사나 조직에 적용 가능한 일반적인 설문입니다.

1. Do you know what is expected of you at work?
Do you know what are wrong ways and right ways of doing your work? Or do you think nobody would notice the difference if you’d switched to coding on your office walls with a crayon marker?
2. Do you have the materials and equipment you need to do your work right?
Are tools and processes supplied and customized for you? Or do you feel that buying and carrying your own stone tablets for writing source code would be an improvement over your current situation?
3. Do you get the opportunity to do what you do best every day?
Are your talents being used to their fullest potential? Or will your mother and her Chihuahua have just about the same chance at success when they’d attempt to take over the work that you do?
4. Did someone recently give you recognition or praise for doing good work?
Is anyone noticing you’re making a difference, in a positive way? Or are they more eager to point at that minor error that almost completely blew up the company, but actually didn’t?
5. Do your colleagues seem to care about you as a person?
Are they interested in your hobbies, your spouse, your friends and family? Or are you not comfortable enough to reveal that you have this fascination for bonsai trees, and are planning to marry one?
6. Are you encouraged to work on your (self-)development?
Has someone discussed with you how you can further improve as a person? Or do you think they won’t even care if you changed into Captain Code, saving the world from bugs and bad formatting?
7. Do people make your opinion count?
Are your colleagues listening to you? Or might you just as well talk to the receptionist’s hair dresser, for all the good it would bring you?
8. Do you feel that your job is important?
Do you understand how your work is a significant part of the value your organization tries to create? Or do you feel that your holidays have about the same amount of impact on the success of your organization?
9. Are your colleagues committed to doing quality work?
Do you feel that doing the best work possible is important to your co-workers? Or do they care more about their working times, their dogs, their collections of beer bottles, and the value of their stock?
10. Do you (or would you like to) consider some colleagues as friends?
Do you enjoy meals, movies, games, or even holidays with some of your colleagues? Or do you intentionally live at the other side of the country, staying as far away from them as possible?
11. Does someone care about the progress of your work?
Is someone interested in what you do at work, and how your work is coming along? Or do they prefer to talk about the weather, or their own heroic stories of saving the company?
12. Are you given the opportunity (time/resources) to learn and grow?
Do you have the means and ability to improve the way you do your work? Or are you expected to learn and grow on your own time, while walking the dog, or taking a shower?

2008년 11월 21일 금요일

책(소프트웨어개발의 모든것)을 미국에 있는 친구에게 보냈다.

며칠 전에 책(소프트웨어개발의 모든것)을 미국에 있는 친구부부에게 보냈습니다.
오늘 받았다고 연락이 와서 잠시 얘기를 했습니다.

그 친구들은 과거 나와 같이 일을 했었던 친구인데,
버클리(UC Berkeley)에서 Computer Science를 전공을 했고, 십여년간 실리콘 벨리에서 소프트웨어 개발자로 일을 하고 있는 친구입니다.

그 친구가 책을 본 소감은 다음과 같더군요.

"책의 내용이 매우 친숙하다. 미국의 개발자들이 당연히 따른 것들이다."

사실 그렇습니다. "소프트웨어개발의 모든것"이라는 책은 소프트웨어 회사라면 당연히 갖춰야할 기초를 다루는 것으로 미국에서는 당연히 되는 것들이 우리나라에서는 너무나도 낯선 것이 많더군요.

Peer ReviewSCMBugTrack, Technical Path, Technical Steering Commitee, Spec, Conding Convention, Risk Management, Branch, Merge, Baseline, Tagging, Change Control, Daily Build, Regression Test, Requirement Engineering, Alpha, Beta, Release Candidate, WBS, B/R, Interface, Non-functional Requirement

이러한 것들이 특이한 것이 아니고 소프트웨어를 개발한다면 그냥 "공기와 물"같은 것인데 말입니다.
이 책을 영어로 번역을 해서 미국에서 판다면 아마 안 팔릴 거예요. 기껏해야 경험이 부족한 대학생들이나 살지도 모르죠. 미국에서는 일단 개발자로 소프트웨어 회사에 들어가면 이 책의 내용들은 2,3년이면 누구나 익히는 것들입니다.
그래서 이런 종류의 책이 미국 또는 한국 어디에도 없나 봅니다.
미국에서는 당연한 내용이라서 없고, 한국에서는 그러한 필요를 못느끼거나 저변이 부족해서 없다고 생각합니다.

하지만 우리나라 소프트웨어 회사들을 보고 개발자들을 만나보면 대단히 뛰어난 기술력과 열정에 비해서 책에서 소개하고 있는 기초에 대해서 취약한 경우가 많습니다. 그러한 소프트웨어 엔지니어링은 학교에서 배우는 것이 아니고 회사에서 자연스럽게 일을 하면서 배우는 것인데, 회사가 기초를 갖추지 못하고 있으니 개발자도 배울 수 없고, 나중에 가르칠 것도 별로 없는 "악순환"이 계속 되는 것이죠.
이건 엔지니어의 책임이 아닙니다. 소프트웨어 회사의 책임이죠. 회사는 입사하는 소프트웨어 엔지니어를 트레이닝 시킬 의무가 있는데, 우리나라 대부분의 소프트웨어 회사는 그냥 개발자에 의존해서 개발자가 하는대로 따라가는 것이 보통의 겨우죠.

그에 비하면 인도는 처음부터 개발자들이 미국에 많이 진출을 했고, 미국의 일을 많이 받아서 해오느라고 미국의 방식대로 그대로 배우면서 소프트웨어 산업이 발전해왔죠. 인도는 정말 잘되어 있습니다. 우리와 소프트웨어 산업의 태생이 다른 인도의 행운이라고 볼 수도 있죠. 모든 업무가 전문적으로 나눠져 있고, 분석, 설계, 테스트, Tech Pub 모든 작업이 전문적으로 진행되고, 문서 작성, 시스템 사용 이런한 것들이 기본적으로 다 갖춰져 있고, Global 표준인 미국의 방식을 따르고 있죠.

솔직히 제가 소프트웨어 컨설팅을 하고 있지만, 단 시일내에 우리나라의 소프트웨어 개발 환경이 좋아지리라고 생각하지 않습니다. 하지만 꾸준한 노력이 필요하고 그 일환으로 책도 쓴 것입니다.
어차피 나를 비롯해서 수많은 소프트웨어 엔지니어들은 이 소프트웨어 바닥이 잘 되어야지 다른 뾰족한 재주가 없으니까요. 지금은 3D 직업으로 점점 인기를 잃어 가고 있지만 소프트웨어 엔지니어가 최고로 대접받는 때가 와야 하지 않겠습니까?

Diff and Merge in SCM(Software Configuration Management)

에 관한 포스팅에 대하여 답변 겸 SCM에서의 Diff와 Merge에 대해서 글을 남겨 봅니다.

일단 헝그리맨님의 글에 대한 답변을 먼저 해야 겠군요.
사실 그동안 소스코드를 Diff하고 Merge하는데는 GUI Diff, Merge툴의 한글 깨지는 문제는 크게 신경을 쓰지 않았습니다.
  • 대부분의 소스코드는 거의 영어로 되어 있고, 
  • 주석에 일부 한글이 들어 갔어도 이부분이 수정되서 Diff, Merge가 필요한 부분이 거의 없었고,
  • 대부분의 머지는 줄단위로 이루어져서 줄 내에서 한글을 깨지게 표현하는 것은 사실 문제가 안되었습니다.
  • 3-way merge를 할때는 오랫동안 Unified diff를 사용했기 때문에 문제가 안되었습니다.
이것은 단지 한글 깨지는 것이 큰 이슈가 아니었다는 얘기입니다.
하지만 한글이 큰 이슈라면 AcroDiff나 WinMerge를 사용하시면 될 것 같습니다.
TortoiseSVN은 외부 Application을 등록하여 사용할 수 있도록 되어 있으니 한글(2byte)문자를 지원하는 AcroDiff나 WinMerge를 사용하세요. 
물론 Araxis Merge같은 상용제품을 사용하시면 금삼첨화지요.
Araxis Merge은 단순히 한글 지원 장점 외에도 3-way Merge를 지원하므로 제대로된 Merge Tool이라고 할 수 있습니다.
3-Way Merge를 지원하는 Merge Tool 중에서 무료로 사용할 수 있는 것은 KDiff3가 있습니다.
GPL 라이센스라서 무료이기는 하나 한글지원에서 약간 문제가 있습니다.
머지 기능 자체의 문제는 아니고 한글 부분이 약간 깨져서 보입니다만 Merge는 잘됩니다.
그래서 저는 KDiff3를 사용합니다.

얘기가 나온 김에 3-Way Merge가 무엇이며 왜 필요한지 "소프트웨어개발의 모든것"이라는 책의 내용을 잠시 소개하겠습니다.

 머지(Merge)
머지는 분기된 소스코드를 하나로 합치는 일이다머지를 능수능란하게사용할 수 있어야 소스코드관리시스템을 원활하게 사용할 수 있다.
머지는 크게 2-way 머지와3-way 머지로 나뉜다. 2-way 머지는 두 개의 파일을 가지고 서로 다른 부분을 비교하면서하나로 합치는 것이다이 방법은 100% 수동에 의존할수 밖에 없다서로 다른 부분 중 어느 것을 빼고 어느 것을 남겨야 하는지 어느 것이 옛날 내용이고어느 것이 새로 바뀐 것인지 직접 보고 판단해야 한다우리가 흔히 보는 머지툴의 대부분이 2-way 머지툴이다.


위 그림은 파일1과 파일2를합쳐서 파일3을 만들려는 것이다파일1과 파일는 원래는 하나의 파일이었으나 과거에 브랜치가 되어서 각각따로 수정된 것이다이 경우 어떻게 합쳐야 할 지 막막하다. B shark일지 monkey일지 판단하는 것이 쉽지 않다. F=mango는 새로 추가된 것인지 원래 있던 것이 반대 파일에서 삭제된 것인지 알기 어렵다따라서 소스코드를 잘 알고 있는 사람이 내용을 모두 보고 판단하는 수밖에 없는 것이다.
하지만 3-way 머지는 방법이 좀 다르다. 두 파일을 단순히 비교하는 것이 아니고 두 파일로 나누어지기 전의 파일도 같이 포함하여 비교하며 머지하는 것이다그렇게 되면 어떤 내용이 추가되거나 삭제되거나 변경되었는지를 알 수 있기 때문에 최종본으로 합치는 일이 훨씬수월하다파일의 충돌만 없다면 자동으로도 머지가 가능하다파일의충돌이 있을 경우에만 충돌된 부분을 사람이 판단하여 통합하면 되는 것이다.


여기서 새로 등장한 파일0은 파일1과파일2가 브랜치 되기 전의 원래 파일이다파일0, 파일1, 파일2를 각각비교하면파일1에서 monkey shark로 수정된 것을 알 수 있다파일2에서 apple은삭제되고 mango가 추가된 것도 알 수 있다이 정도면사람이 별도로 판단할 필요 없이 자동으로 머지가 가능하다. 이러한3-way 머지툴에는 다음과 같은 것들이 있다.
  • Perforce Merge
    • Publisher: Perforce software
    • License: 무료
  • Araxis Merge
    • Publisher: Araxis ltd.
    • License: 유료
  • KDiff3
    • Publisher: KDevelop
    • License: GPL
이 중에서 KDiff3는 인터넷을 통해서 쉽게 구하여 사용할 수 있다.


3-way 머지를 이용하면 또 다른 기능을 이용할 수도 있는데부분 머지(Range Merge)가 바로 그것이다예를 들어 브랜치를 하여 수정한 여러 부분에서 특정 부분만 트렁크와 머지를 하고 싶을 때가 있다고객의 요구에 의해 브랜치를 했고해당 브랜치에는 고객의 특별요구 기능이 반영이 되어 있었다그런 다음 브랜치에서 발견한 버그를 수정했는데이를 트렁크에도 반영하고 싶을 때가 있다이 경우에 3-way 머지를 이용하면 다른 부분은 빼고 버그를 수정한 부분만 골라서 머지를 할 수 있다.


소스코드관리시스템과 3-way 머지툴을 효과적으로 사용하면 머지작업이아주 효율적으로 진행된다그러나 3-way 머지가 매우유용한 방법인 것은 사실이나 100% 자동에 의존할 수는 없다.3-way 머지툴이 충돌없이 머지에 성공했다 하더라도그 결과를 눈으로 직접 확인하는것이 더욱 안전할 것이다.

2008년 11월 19일 수요일

SRS(Software Requirements Specification)의 중요성

본 블로그에서 소프트웨어 개발, 소프트웨어 공학에 대한 여러 주제에 대해서 다루겠지만, 
특히 나는 요구사항 특히 SRS에 대해서 많이 다루려고 합니다.
"소프트웨어개발의모든것"이라는 책에서도 요구사항에 대해서 가장 중요하게 다루고 있지만 지면의 한계와 다양한 독자층의 눈높이를 맞추기 위해서 욕심보다는 많이 설명하지 못하는 측면이 있습니다.
그래서 소프트웨어 개발단계에서 가장 중요한 "요구사항"에 대해서 천천히 여러분들과 의견을 주고 받으면서 심도있게 다뤄볼까 합니다. 제가 세상의 모든 경우의 요구사항 분석 기술 및 경험이 있는 것이 아니니 여러분들과 토론을 하면서 또 많이 배울 것을 기대하고 있습니다.

먼저 제가 책에서 요구사항에 대해서 설명한 내용을 앞부분을 약간 소개할까 합니다.

 요구사항 분석

소프트웨어 프로젝트에 있어서 가장 흔한 실수 중의 하나가 요구사항이 불명확한 상태에서 급하다는 이유로 일단 설계, 구현을 시작하는 일이다. 어떤 경우는 스펙문서가 아예 없는 상태에서 프로젝트를 진행하는 경우도 있다. 또는 간단한 요구사항 목록을 가지고 스펙이라고 착각하는 경우도 많다.
제대로 된 요구사항 개발 없이 프로젝트를 성공적으로 수행하는 것은 거의 불가능하다. 고객의 요구사항을 상세히 기술하였다고 해서 좋은 요구사항은 아니다. 고객도 자신이 원하는 것을 자세히 모르는 경우가 아주 흔하기 때문이다. 고객의 요구사항을 단순히 기술한 정도의 요구사항은 프로젝트 후반에 많이 바뀔 수 있는데, 요구사항 개발 시 간단히 해결할 수 있는 것을 프로젝트 후반이나 유지보수 시까지 와서야 처리함으로써 수십 배의 비용을 추가로 치르는 경우도 있다.
요구사항 개발은 단순히 요구사항을 옮겨 적는 일이 아니다. 요구사항을 수집하고, 분석하고, 정리하고, 리뷰하는 일을 반복하여 완성도를 높여가는 일이다.
책을 보고, 샘플을 보고, 템플릿을 이용해서 독학함으로써 SRS를 잘 쓰는 것은 거의 불가능하다. 책이 도움은 될 수 있으나, SRS를 제대로 쓰려면 제대로 된 회사에 가서 몇 년 동안 일하면서 배워야 한다. 때에 따라서는 전문가에게 컨설팅을 받는 것도 좋은 방법이다. SRS는 기능공처럼 기법에 따라 작성하면 되는 것이 아니라 인간의 판단이 핵심인 문서이기 때문에 작성이 생각처럼 간단하지 않다.

 요구사항의 중요성

요구사항 문서는 프로젝트에서 작성하는 산출물 중에서 가장 중요하다. 요구사항 문서인 SRS는 소프트웨어 프로젝트의 기둥이다.
소프트웨어 시스템 구축에서 가장 어려운 부분은 무엇을 구축할 것인지를 정확하게 판단하는 것이다. 그러나 구현을 시작하기 전에 요구사항을 완벽하게 파악하는 것이 불가능한 경우가 많다. 그렇다고 해서 요구사항 개발에 소홀해서는 안 된다. 시간이 허락하는 한 최대 한도로 많은 정보를 파악하는 것이 좋다. 
잘못된 요구사항은 많은 재작업 비용을 필요로 한다. 재작업 비용은 일반적으로 전체 개발 비용의 30~50%에 이르는 것으로 알려져 있다. 요구사항 오류로 인한 재작업 비용은 전체 재작업 비용의 70~85%에 이른다. 잘못된 요구사항, 부족한 요구사항은 일정을 지연시키며 많은 추가 비용을 발생시킨다. (출처, Software Requirements, Karl E. Wiegers, Microsoft Press)
완벽하게 상세한 요구사항이 가장 좋은 요구사항은 아니다. 요구사항은 이해하기 쉽게 간결함을 추구해야 한다. 간결하지만 충분히 설계, 구현할 수 있어야 한다. 그리고 요구사항 문서는 모든 관련자가 충분히 검토해야 한다.



요구사항 오류는 개발 단계가 지나가면 갈수록 그 수정 비용이 기하급수로 증가한다. 유지보수 단계에서 요구사항 오류를 바로 잡으려면 요구분석 단계에서 바로 잡는 것보다 200배의 비용이 더 드는 것으로 알려져 있다. 충분히 검토하여 오류가 없는 요구사항을 만드는 것이 프로젝트를 성공으로 이끄는데 가장 필요한 핵심이다.

SRS란?

요구사항 분석 문서의 종류는 수없이 많다. 개발 방법론에 따라서 제시하는 요구사항 문서가 다르고, 그 개수도 다르다. 여기서 소개할 문서는 SRS이다. SRS는 이 책 전체에서 소개하는 많은 문서 중에서 가장 중요하다. 프로젝트를 성공으로 이끄는데 가장 중요한 핵심이기 때문이다. 만약 소프트웨어 프로젝트에서 문서를 딱 하나밖에 만들 시간이 없다고 하면 SRS를 만드는 것이 좋을 것이다.




SRS는 IEEE에서 만든 가이드와 표준 Template이 있다. 회사들마다 사용하는 Template이 약간씩 다르지만 문서이름, 목적, 취지는 전세계적으로 표준이라고 보면 된다. 소프트웨어 개발 회사라면 회사에 맞게 각자 커스트마이즈 된 SRS Template을 가지고 있어야 한다.

2008년 11월 15일 토요일

Release Branch, Function Branch and Customer Branch

서영아빠님의 "브랜치를 이용하여 운영환경에 선별적으로 배포하기"란 글을 보고 소프트웨어 프로젝트에서 브랜치란 어떤 의미를 가지는지 "소프트웨어 개발의 모든것"이라는 책에서 이에 대하여 소개한 내용이 있는데 이를 인용하여 설명을 하려고 합니다.

여기서 소개하는 브랜치에 대한 얘기의 핵심은 브랜치의 위험성에 대한 "경고"입니다.
브랜치는 위험하지만 소프트웨어 개발에서는 흔히 꼭 필요하게 되어서 철저히 통제가 되어야 한다는 것입니다.

 브랜치(Branch)

브랜치란 필요에 의해서 소스코드를 분기하는 것이다. 
브랜치를 얼마나 잘 통제하는가가 훌륭한 소프트웨어 회사와 평범한 소프트웨어 회사를 구별하는 핵심 요소 중 하나이다. 
브랜치를 해야 하는 경우를 예로 들면 다음과 같다.

  • 제품을 출시 후 유지보수를 하면서 동시에 업그레이드 프로젝트를 진행할 경우
  • 이미 출시 된 제품에 복잡한 기능을 추가하려고 할 경우
  • 고객이 제품에 특정 기능을 넣어 달라고 요구를 하는데, 그 기능이 제품의 표준 기능에서 벗어날 경우
  • 고객이 제품에 특정 기능을 넣어 달라고 요구를 하는데, 표준 기능으로 넣을 시간이 부족한 경우

제품 출시 후 유지보수와 업그레이드 프로젝트를 진행하면서 하나의 소스코드를 같이 사용한다면 완전히 뒤죽박죽이 될 것이다. 아직 완성되지 않은 기능들이 고객에게 전달 될 수도 있다. 이 경우 소스코드를 브랜치하여 브랜치 된 소스코드를 유지보수를 위해 사용할 수도 있고, 업그레이드 용으로 사용할 수도 있다. 상황에 따라서 적절하게 선택하면 된다. 가능하면 적게 바뀔 것을 브랜치로 사용하는 것이 좋을 것이다. 왜냐하면 브랜치는 나중에 트렁크(Trunk)와 머지를 할 것이기 때문이다. 이렇게 서로 다른 소스코드를 가지고 개발하다가 업그레이드 프로젝트가 끝날 때쯤 그 동안 유지보수를 하면서 버그를 수정하거나 일부 기능을 추가한 것들을 서로 머지하게 된다. 이러한 브랜치를 릴리즈 브랜치(Release Branch)라고 부른다.
이미 제품이 출시되어서 유지보수를 하고 있을 경우, 시간이 많이 걸리거나 리스크가 큰 기능을 추가할 때도 브랜치를 사용할 수 있다. 예를 들어 어떤 제품이 2주일에 한번씩 업데이트를 한다고 할 때, 어떤 기능은 구현하는데 4주가 걸린다면 2주 만에 업데이트를 할 때, 완성되지 않은 기능이 포함될 수 있다. 또는 구현의 가능성이 확실하지 않은 기능을 원래 소스코드에서 개발하느라고 소스코드를 마구 건드릴 경우 나중에 기능을 빼려고 해도 깔끔하게 원래대로 되돌려 놓기가 쉽지 않다. 이럴 때 브랜치를 해서 해당 기능이 완성된 후 메인 소스코드와 머지를 하면 된다. 이러한 브랜치를 기능브랜치(Function Branch, Feature Branch)라고 부른다.

브랜치 중에 가장 문제가 되는 경우는 고객의 특수한 요구를 만족시키기 위해서 제품이 분기되는 경우(Customer Branch)이다. 제품이 분기된 뒤, 나중에 머지되지 않고 영원히 브랜치가 유지되는 경우가 많다. 브랜치를 만들고 어느 시점이 지나면 원래 소스코드와 브랜치가 너무 차이가 많이 나서 머지가 거의 불가능해지기 때문이다. 
브랜치를 쉽게 생각하고 일단 소스코드를 분기해서 별도의 제품을 만들기 시작하는 것은 되돌아 올 수 없는 강을 건넌 것이나 다름없다. 경험이 부족한 개발자는 브랜치의 부담을 우습게 생각하기 쉽다. 실제로 초기에는 브랜치가 있어도 견딜만하고 관리할 만 하다. 특히 브랜치를 해야만 매출을 일으키는 경우라면 브랜치의 유혹을 뿌리치기가 쉽지 않다.

그러나 이렇게 브랜치를 계속 만들다 보면 더 이상 감당이 안 되는 때가 오게 된다. 회사가 어느 정도 매출이 일어나고 잘되기 시작하면 과거에 많이 만들어 놓은 브랜치가 더욱 발목을 잡는다. 어차피 제품이 많이 팔리지도 않았다면 문제가 될 것도 없다. 오히려 회사가 잘될 때 문제가 된다. 이쯤 되면 제품의 업그레이드나 신제품 개발보다는 브랜치 관리에 더 많은 노력을 기울일 수밖에 없게 된다. 버그를 하나 고쳐도 여기저기 브랜치를 다 손대야 한다. 어느 브랜치를 어느 고객이 쓰고 있는지 헷갈려서 배포 사고도 가끔 발생한다. 무슨 툴을 하나 만들어도 각 브랜치마다 다르게 개발해야 하는 어려움이 발생한다. 

브랜치가 많아지면 웬만큼 관리를 잘하지 않고는 어느 브랜치에 무슨 기능이 포함되어 있는지 정확하게 파악하기 힘들어 진다. 초기에 브랜치를 만들었던 개발자들도 얼마 간은 브랜치 내용을 정확하게 기억하고 있을지 모르지만, 시간이 지나면 브랜치를 만든 개발자마저도 브랜치 내용을 정확하게 기억하기 어려워진다. 게다가 문서는 없고, 사람마저 바뀌어버리면 정말 알 수 없는 상황이 된다. 이로 인한 문제를 말하자면 끝이 없지만, 한마디로 아수라장이 되어버린다고 할 수 있다.

브랜치가 필요하다고 해서 개발자가 원할 때마다 브랜치를 해서는 안 된다. 브랜치를 하려면 개발 조직의 최고 책임자나 위원회의 허락을 받도록 하는 것이 좋다. 이 때는 브랜치를 해야 하는 이유를 타당하게 설명해야 하고 가능하면 빨리 머지를 할 수 있는 계획도 세워야 할 것이다.

특히 영업 지향의 회사에서는 브랜치의 위험성에 대해서 이해하지 못하는 경우가 많다. 단기적인 매출의 유혹이 회사의 미래를 망치는 경우를 종종 보게 된다. 고객마다 소스코드가 다르고 매번 각 사이트를 지원하기 위해 개발자들이 고객 전용 소스코드를 수정하고 있어도 이를 당연한 것으로 생각하기 쉽다. 이렇게 되풀이 되는 일들이 개발자들의 사기를 떨어뜨리는 것은 물론이다.