|
|
Recent Comments 가져오기
요즘사이트들은 거의 utf8을 기준으로 만들어져있겠지만 joinc 사이트가 만들어진 2000년에는 euckr이 대세였고, 시대조류? 맞지 않게 euckr을 유지하고 있다. utf-8로 바꿀걸 생각해봤지만 워낙에 귀찮아서..
문제는 disuqs가 euckr을 전혀 지원하지 않는데 있다. 그러다보니 브라우저에 따라서 컨텐츠가 깨지는 문제가 발생한다. Firefox 에서는 잘되는데.. IE에서는 깨진다. 암튼 언제나 IE가 문제다. 그래도 (아마도)80%이상의 방문자가 IE를 사용하니 IE에서도 보이게 해줘야지..
해서 다음과 같은 간단한 함수를 만들어서 disuqs의 recent comment 컨텐츠 자체를 euckr 로 변경해 버렸다. php의 iconv함수를 사용했다.
function get_recent_comment() { $contents = array(); $handler = fopen('http://disqus.com/forums/joinc/combination_widget.js?num_items=5&color=blue&default_tab=recent','r'); if(!$handler) return 0; while(!feof($handler)) { $line = fgets($handler,1024); $line = iconv('utf-8', 'euckr', $line); if(ereg("^\t +<h3>", $line)) $line = str_replace('Recent Comments', '최근댓글', $line); if(ereg('combo-tab-recent', $line)) { $line = str_replace('Recent','최근댓글', $line); } if(ereg('combo-tab-people', $line)) { $line = str_replace('People','댓글러', $line); } if(ereg('combo-tab-popular', $line)) { $line = str_replace('Popular','높은인기', $line); } if(ereg("dsq-widget-meta", $line)) { $line = str_replace('hours ago','시간 전', $line); $line = str_replace('minutes ago','분 전', $line); $line = str_replace('Some thread attached to test page','FrontPage', $line); } $contents[] = $line; } $text = join($contents); return <<<FOOT <script type="text/javascript"> $text </script> FOOT; }
이왕 이렇게 된게 Recent Comments같
은 문자열까지 한글로 바꿔 버렸다. str_replace에 비용이 좀들어갈 것 같은데, 나중에 시간이 되면 static 페이지를
생성하는 스크립트를 만들어 봐야 겠다. 우선은 이것으로 만족. 사이트 옆에 붙여놓은 위젯을 보면 (눈속임)한글화가 된 것을
확인할 수 있다. 아직 blog에는 적용하지 못했고 joinc wiki 에만 적용했다. 시간이 남으면 blog에도 적용시켜야지. :::

기술이 중요한게 아닌듯
구글 OS는 티맥스 윈도우 기술력의 1/5도 안된다고말했던가 ? 중요한건 기술이 아닌 것 같다. disqus를 보면 그런생각이 든다. 개인적으로 이러한 댓글 시스템을 원했기 때문에 유독 반갑게 받아들이긴 했지만 말이다.
disqus는 소셜댓글 시스템을 표방한다. 사이트와 서비스에 관계없이 붙여 놓으면 서로
커뮤니케이션이 가능하며, 자신의 댓글을 쉽게 관리할 수 있도록 도와준다. 여기 저기 사이트 돌아다니면서 댓글 달아 놓은게
얼마던가. 그러나 그렇게 하면 뭐하나. 며칠 지나면 자주방문하는 사이트의 댓글이 아닌 한은 몽땅 잃어버리고 만다. 댓글이라는
것이 서로간의 커뮤니케이션을 위한 도구라고 하는데, 써놓고 잃어 버린다면 이게 무슨 소용인가. 소통을 위한 시스템인데, 막상
소통의 접점을 잃어버리게 되고 만다. 그렇다고 댓글 써놓은 사이트와 포스트를 일일이 관리할 수도 없는 일이고.
disqus는 공통의 저장소에 댓글을 저장하며, 저장된 댓글은 open api 를 이용해서 access 가능하도록 하고 있다.
이렇게 함으로써 사이트에 관계없이 댓글을 사용할 수 있도록 하고 있다. 댓글이 공통의 저장소에 관리되므로 댓글관리도 물론
편하다. 간단하게 자신의 댓글과 그 댓글에 댓글까지를 한꺼번에 관리할 수 있다. 거기에 자신의 email로 댓글들이 배달되니
여하튼 이처럼 편할 수 없다.
disqus 시스템이 나의 적성에 맞는 또다른 이유는 이것 저것 가져다가 붙이는 걸 좋아하는 내 성격에 맞기 때문이다. 어떤
차이에서 인지는 모르겠지만 영미권 얘들의 사이트를 보면 이것저것 공개된 툴들을 가져다 붙이는 형식을 선호하는 것 같다. 반대로
우리나라의 사이트는 하나로 끝나는 통패키지를 선호하는 것 같다.
가상 게시판
예컨데 가상 게시판같은 거라고 보면 될 거 같다. 예전에 가상 게시판같
은걸 생각한적이 있었다. 마음대로 게시판을 생성할 수 있고, 또한 그 게시판들끼리 게시내용들이 공유되는 그런 시스템이였다. 실제
나는 참가하지 않았지만 그러한 프로젝트도 진행되었었다. 그런데 완성되지 못하고 disqus는 완성이 되었다. 어디에서 그 차이가
나는 걸까. disqus와 예전의 그 프로젝트를 보면, 얼마나 많은 기술이 들어갔는지 아키텍쳐는 얼마나 훌륭한지가 중요한게 아닌
것 같다란 생각이 든다.
고객이 원하는게 아닌 내가 원하는게 무엇인지를 알고 그걸 만들기 위해 노력하는것 그게 결정적인 차이인 것 같다. 그때 그 프로젝트가 실패한 이유는 사용자가 원하는 걸 만들려고 했기 때문이 아닐까. ?
개인적인 생각인데, disqus에서 제공하는 open api 를 이용하면 댓글시스템을 넘어서서 가상게시판도 만들수 있을 것 같다. disqus api를 분석해서 만들어볼 요량이다.
joinc에 붙이기
현재 joinc 위키 페이지와 개인 블로그에 disqus를 붙였다. 그리고 개인적으로 만들고 있는 영문 맨페이지에도 disqus를 붙였다. :::

미디어를 장악하려는 이유
미디어를 제어하는 자가 세계를 지배한다고 했다. 마샬 맥루한은 기계는 인간의 신체의 확장이라고 했다. 인간의 시각, 촉각,
운동능력을 확장하고 강화하는 것을 기계로 본것이다. 이중에서 비교적 최근에 생겨난 대중미디어는 인간의 중추신경계를 확장시키는
기계로 보았다. 확장된 중추신경계는 외부의 중추신경계에 연결되는데, 이것이 이른바 대중미디어라는 전기로 작동되는 새로운 종류의
기계인 것이다. 매트릭스에서 인간의 중추신경계가 거대 컴퓨터에 묶여있는 그러한 광경을 생각하면 좀더 쉽게 이해할 수 있을 것이다.
인간은 대중미디어를 통해서 의식을 외부세계로 까지 확장시킬 수 있었고 지구촌으로 묶일
수 있게 되었다. 문제는 대중미디어의의 중추신경적인 특징이다. 중추신경계가 모든 말단신경을 통제하고 제어할 수 있듯이, 결국
대중미디어라는 중추신경계에 묶인 인간은 대중미디어의 완전한 통제를 받을 수 밖에 없다는게 맥루한의 진단이었다.
독재적인 정권이 미디어를 장악하려는 이유는 대중미디어를 통제함으로써 인간의 의식을 마음대로 주무를 수 있다는 이러한 통찰에
기인한다. 대중은 미디어가 전해주는 정보만을 사실로 받아들이게 되고, 받아들인 정보대로 세상을 보게될 것이기 때문이다.
중추신경계는 또한 감각을 마비시키는 기능이 있다. 만약 몸의 어떤부위에 상처가 발생했고, 그 상처가 통제범위를 넘어서는 상처라면
중추신경계는 그 부위의 감각을 마비시켜버린다. 이것은 심각한 고통으로 부터 생명체자체를 보호하려는 일종의 방어기재다. 손가락이
짤린 쇼크때문에 생명을 잃어버리는 것보다는 해당 부위의 감각을 마비시키건나 - 몰핀과 같은 마약성분을 다량으로 분비하는 식으로
- 인지능력을 떨어트려서 생명을 보호하는게 더 유리하기 때문이다.
마찬가지로 중추신경계로써 작동하는 대중미디어는 말단에 위치한 대중의 감각을 마비시킬 수 있다.
요즘들어 계급배반이라는 얘기를 종종 들을 수 있다. 자신의 이익에 반하는 정치세력에
투표를 하고, 자신의 이익에 반하는 정책에 무감각하거나 오히려 그것을 긍정적으로 받아들이는 이율배반적 행동을 말한다. 여러가지
이유를 들어서 계급배반의 매커니즘을 설명하려고 하는데, 대중미디어야 말로 대중이 계급배반적인 행동을 하는 진짜이유가 된다.
대중미디어가 말단에 위치한 대중의 감각을 마비시켜 버리는 것이다. 그러므로 자신들이 상처를 입었음에도 불구하고 상처를 입었는지를
잊어버리게 된다. 자신에게 상처를 입히기 위해서 메스가 가해지고 있음에도 불구하고 그 상황을 무심하게 받아들이는 것이다. 오히려
그 상처에서 멀리 떨어져 있는 직접적으로 피해를 받지 않는 위치에 있는 외부에서 그 상황을 심각하게 받아들인다. 최근 2MB의
부자감세정책을 포함한 일련의 저소득에 부담을 지우는 정책들에 대해서 피해당사자인 저소득층 보다, 그 피해에서 멀리 떨어진
고소득자가 오히려 걱정을 하는 이유는 이때문이다. 참고 : MB의 든든한 지지층, 저소득층
현 정부의 일련의 정책은 신자유주의 강화를 통한 소수에대한 부와 권력의 집중이며, 필연적으로 빈부격차가 커질 수 밖에 없게 될 것이다. 즉 대중의 상당수가 소수를 대신해서 상처를 받게 될 것이란 얘기다. 이럴경우 저항은 필연적이다. 이러한 저항을 막기 위해서는 감각을 마비시킬 필요가있다. 무엇을 통해서 ? 중추신경계인 미디어의 장악을 통해서. 지금 정부는 자본과 함께 필사적으로 미디어를 장악하려고 할 것이다. 2009년 6월 미디어법을 여당단독으로 그리고 필사적으로 처리하려는 이유다.
MBC 죽이기
중추신경계가 두개가 있으면, 통제가 힘들어진다. 한쪽 중추신경계는 상처의 감각을 마비시키려고 한다. 그런데 다른쪽 중추신경계가
고통을 느끼려고 한다면 혼란스럽지 않겠는가 ? 독재권력은 당연히 이러한 상황을 달갑지 않게 생각한다. 그들은 이것을 혼란이라고
한다. 그들에게 필요한건 단지 하나의 사실, 하나의 통제가능한 중추신경계가 필요할 뿐이다. 그래야 감각을 효과적으로 마비시켜서
계급배반적인 인간, 다른 말로 노예이면서 노예인줄 모르는 상태로 살아갈 수 있는 인간을 만들 수 있을 것이기 때문이다. 그러므로 그들은 MBC를 죽여야만 한다.
인터넷 미디어의 통제
문제는 인터넷 미디어이다. 인터넷 미디어는 중추신경계의 역할을 하는 대중미디어와는 성격이 다르다. 인터넷은 중심이 없으며,
제어할 수 없다. 신경 말단이 중추신경계에서 떨어져서 그들 스스로 의식을 가지고 활동할 수 있는 매커니즘을 가지고 있다. 상처가
별거아니라고 마비시키려는 중추신경계의 의도를 무산시킬 수 있다. 우리는 고통스럽다고 아우성친다. 도와달라고 지금 상황이 나쁘며,
무언가 잘못되어가고 있다고 주변에 신호를 보낸다. 인터넷 미디어가 항상 시끄러운 이유이며, 권력의 의도와 달리 쉽게 제어되지
않는 이유다.
당연히 독재정권에게 인터넷 미디어는 없어져야할 독이된다. 모든 독재정권은 인터넷을 통제하려고 하며, 독재정권의 예외없는 특징이기도 하다.
자 이제 상황이 이러하니 매우 독재스러운 것처럼 보일락 말락하는 이 정권은 인터넷 미디어에 대한 통제를 시도하게 된다. 이러한 중앙통제기관이 없는 풀뿌리 미디어를 통제하기 위한 가장 효율적인 방법은 점조직적인 감시망을 통한 감시와 처벌이다. 북한에서 주민을 통제하려고 시행했다는 5호 담당제 요런거 비슷한 거다.
그래서 법을 만들었다 ? 어떤 법 ? 귀에 걸면 귀걸이 코에 걸면 코걸이가 될 수 있는 법. 저작권법. 박정희, 전두환 독재시절의 국가보안법이 코에걸면 코걸이 귀에걸면 귀걸이 였던 것 처럼 말이다. 감시하다가 요놈 아니다 싶으면, 귀에 걸거나 코에걸어서 엄정하고 공정한 법으로 처벌하면 되니까 말이다. 요즘 들어 엄정하고도 공정한 법의 집행을 강조하는 이유다. 포괄저기고도 추상적이고도 자의적인 해석이 가능한 법을 만들어둔다음 포괄적으로 감시하고 포괄적으로 처벌 하기 위함이다. 포괄적인 방법으로 감시하고 처벌하려고 하면, 당연한 저항이 예상되는 바 엄정하고도 공정한 법의 집행을 운운하면서 그러한 분위기를 만들어가려고 하는 것이다. 이런걸 야경국가라고 하던가 ? 조만간 악법도 법이다라는 얘기가 나올지도 모를 일이다.
정권입장에서 가장 시끄러운 인터넷 미디어는 블로그다. 이처럼 눈엣 가시가 없을 것이다. 그래서 귀에걸면 귀걸이 코에걸면 코걸이
저작권 법을 만들어 내어 놓으셨다. 맘만먹으면 99.9% 잡아들이거나 아예 해당 서비스를 폐쇄할 수 있도록 법을 아주 해괴하게
만들어 놓으셨다.
다음은 인용이 저작권법에 걸리지 않을 요건이다.
인용의 성립요건
- 보도 비평 교육 연구 등을 위한 인용일 것
- 정당한 범위 내일 것(인용저작물과 피인용저작물이 양적 질적으로 주종관계가 성립하며 분명하게 구별될 것)
- 공정한 관행에 합치될 것(저작물 이용의 목적과 방법이 건전한 사회통념에 비추어 판단할 때 공정한 관행에 합치되며, 출처표시를 해야 할 것
그런짓을 하지 않으면 되지 않는가 ?. 문제될게 뭐가 있냐고 ? 아주 자의적이라는 점이 문제라는 것이다. 게다가 악질적인 것은
이전처럼 친고죄가 아니라는 점이다. 저작권자의 신고가 없더라도 검찰과 경찰이 자의적으로 판단해서 기소할 수 있다는 점이다. 물론
기소된다고 해서 바로 범죄자가 되는건 아닐 것이다. 법원의 판단이라는게 기다리고 있을테니까 말이다. 그러나그렇다고 괜찮은가 ?
한밤중에 검찰이 국가보안법을 위반한 소지가 있다고 해서 집안을 쑥대 받으로 만들어 놓고 기소한 다음이라도 법원에서 무죄로
판결받으면 괜찮은 것인가 ? 명백히 무죄로 판명될것이 예상되든지 말든지간에 일단 검열받고 기소된다는 자체가 개인에게는 엄청난
스트레스이자 두려움일 거란건 말할 필요가 없다. 감시와 통제 기제로 작동을 할 수 있는 길을 터놓으셨다는 얘기다. 특정 블로그
특정 사이트의 권력에 대한 비판이 마음에 들지 않는다 하면, 귀에걸면 귀걸이가 되는 법을 가지고 일단 쑥대받을 만들어 놓으면
된다.
:::

논어 ISBN : 9788970650340를 읽고..
서점에 가면 프로젝트 관리와 관련된 책들이 널려있다. 특히 애자일 열풍?이 불어닥치면서 애자일 관련된 책들만해도 수십권은
되어보인다. 그런책들은 언제 시간나면 한번 읽어보기로 하고, 논어에 나오는 격언들을 프로젝트관리에 적용시켜보면 어떨까라는 생각이
느닷없이 든김에 생각을 정리해 보기로 했다.
공자왈 백성들을 정치로 인도하고 형벌로 다스리면 백성들은 형벌을 면하고도 부끄러워함이 없다. 그러나 덕으로 인도하고 예로써 다스리면, 백성들은 부끄러워할 줄도 알고 또한 잘못을 바로잡게 된다.
일정으로 프로젝트와 팀원을 제어하려고 하면, 팀원은 일정을 어기게 되더라도 부끄러워함이 없어진다. 많은 경우 이러한 일정은
(마음으로)동의하지 않은 일정이기 때문이다. 사람은 동의하지않은 권위에는 복종하지 않으려고 한다. 일정에 차질이 생기면 쉽게
핑계를 댈 수 있다. 마음으로 받아들이지 않게 된다. 일정에 사람을 맞추는 것보다 사람에 일정을 맞추어야 하는게 아닐까란 생각을
해본다. 애자일관리 기법에서 일정보다 사람을 우선시 하는 이유도 여기에 있을 것이다. 일정은 따라오는 것이지 따라가는 것이 아니다.
공자왈 군자는 천하에서, 반드시 그래야만 한다는 것도 없고, 절대로 안된다는 것도 없으며, 오직 의로움만을 따를 뿐이다
반드시 내가 생각한데로 이렇게 이렇게 해야만된다라고 결정하고 그것을 지킬것을 명하는 경우가 있다. 특히 그 프로젝트를 내가 잘
알고 있다고 생각하는 리더의 경우에는 더욱 그러할 수 있다. 아무리 뛰어난 리더라도 프로젝트를 제대로 이해하는건 거의 불가능하게
되었다. 정형화된 제조업이라면 어떠할지 모르겠지만, 소프트웨어 관련 프로젝트 특히 인터넷
관련 프로젝트에서는 더욱 그러한것 같다. 자신의 생각을 고집하지 말고 융통성있게 남의 의견을 받아들여야 하지 않을까. ? 물론
그러하기 위해선 수평적 관계형성이 중요할 것이다. 소프트웨어 개발관련 조직에서 수평적 관계형성이 주목받는 이유일 것이다.
공자왈 군자는 말에 대해서는 모자라는 듯이 하려하고, 행동에 대해서는 민첩하려고 한다
리더가 너무 똑똑하고 그걸 내세우면 프로젝트가 산으로 가는 경우가 많은 것 같다. 한사람이 모든것을 파악할 수 있는 시대가 아니다. 모든걸 이해하고 있다고 생각하는 순간 프로젝트는 산으로 향하신다.
자유왈 임금을 섬김에 번거롭게 자주 간언을 하면 곤욕을 치루고 치욕을 당하게 되고, 친구에게 번거롭게 자주 충고하면 곧 소원해진다.
시시콜콜한거 까지 일일이 참견하고 간섭하는 걸 좋아하는 사람 없을 거다. 충고나 간섭은 필요한 때에 필요한 만큼만 하는게 좋을 것 같다. 상대방이 감당할 수 없는 충고는 충고가 아니다. scrum같은 개발방법론에서는 일단 개발사이클이 결정되면, 외부에서는 절대 참견하지 못하도록 하고 있다. 굳이 보고싶다면 참관만 허용하는 정도이다. 참견은 개발주기가 끝난 다음에 이루어진다. 시시콜콜한 충고와 간섭을 없애기 위함이다.
공자왈 군자는 절박한 것은 도와주지만 부유한자가 더 부자가 되게 도와주지 않는다
2MB옹은 지금 하고 있는 짓이다. 절박한 사람의 것을 빼앗아서 부유한자가 더 부자가 되게 하고 계시다. 잘하는 사람은
잘하는데로 되었으니 그냥 두어도 괜찮다. 뒤쳐지는 사람에게 더 많은 배려가 필요하다. 이렇게 행동하면 되지 않을까 ? 그렇지만
실제는 이 반대인 경우가 많은 것 같다. 예컨데 심복을 키우겠다 라든지 뭐 그런 이유로 말이다.
자로가 여쭈었다. 선생님께서 삼군을 통솔하신다면 누구와 함께 하시겠습니까 ? 공자께서 말씀하시길 맨손으로 범을 잡고 맨몸으로 황하를 건너려다 죽어도 후회가 없는 사람과는, 나는 함께하지 않겠다. 반드시 일을 대담에 신중하게 하고, 계획을 잘 세워 일을 이루는 사람과 함께 하겠다.
욕심이 앞서면 프로젝트를 망친다. 예컨데, 열정과 감정은 다르다.!? 알수 없는 내일을 위해서 오늘 하루, 이한몸 불사른다는
마음가짐을 버리자. 몸과 시간으로 떼우면 일정같은거 맞출 수 있을 것이란 것은 그나마 굴뚝산업에나 통해먹는 행동양식이다.
공자왈 부가 만약 추구해서 얻을 수 있는 것이라면, 비록 채찍을 드는 천한 일이라도 하는 하겠다. 그러나 추구해서 얻을 수 없는 것이라면 내가 좋아하는 일을 하겠다
어떤 결과를 얻기 위해서 일을 진행하기 보다는 그 자체를 좋아할 수 있어야 하지 않을까 ? 혹은 좋아할 수 있는 환경을 만들어야 하지 않을까라는 생각이 든다.
군자는 평온하고 너그럽지만, 소인은 늘 근심에 쌓여있다.
근심에 쌓이는 프로젝트가 있고, 그렇지 않은 프로젝트가 있다. 근심이 쌓이는 프로젝트라면, 프로젝트가 제대로 진행되고 있는 것인지 되짚어볼 필요가 있다.
마굿간에 불이 났었는데, 공자께서 퇴근하시어 사람이 다쳤느냐라고 물으시고는 말에 대해서는 묻지 않으셨다.
자본을 신으로 모시는 자본주의 사회이다 보니 크게는 회사이익, 작게는 프로젝트이익에 해를 끼치면 때때로 사람이 사람취급을 받지
못하는 경우가 생겨난다. 프로젝트에 불이 나지 않도록 하는게 우선이겠지만, 일단 불이 났다면 사람을 보듬는게 우선이 되어야
하겠다. 물론 쉽지 않은 일이겠지만.
공자께서 말씀하셨다. 지나친 것은 모자란 것과 마찬가지이네
중궁이 정치에 대해 여쭙다. 공자께서 말씀하시길 먼저 실무자들에게 일을 분담시키고, 작은 잘못은 용서해 주며, 현명한 인재를 등용하거라
정치와 관련된 공자의 격언들을 보면 윗사람은 사사로운 것까지 통제하려하면 안된다는 가르침이 자주 등장한다. 예컨데 리더는 큰
방향을 잡아주는 사람이지 사사로운 것까지를 전부 간섭해서는 안된다는 것이라 하겠다. 비슷한 맥락으로 사사로운 것에 연연하면,
큰걸 이루지 못한다고 하셨다. 큰 방향을 잡고, 그 방향안에서 수행해야할 일들은 실무자에게 맡기고 소소한 잘못은 용서한다.
이렇게 하려면 역시 어느정도의 대범함과 느긋함이 있어야 할듯 싶다. 사람을 믿을려면 대범함이 필요할테고, 대범하려면 멀리봐야
할테니 말이다.
섭공이 정치에 대해서 묻자, 공자님께서 말씀하시길 가까이 있는 사람들은 기뻐하고, 먼 데 있는 사람들은 찾아오도록 하는 것입니다라고 하셨다.
프로젝트를 하다보면 정치관련된 얘기가 많이 오간다. 이때 정치는 공자님이 말하는 정치와는 분명히 다르다. 정치라는게 무엇인지 생각해봐야 하지 싶다.
자하가 정치에 대해 여쭙자, 공자께서 말씀하시길 빨리 성과를 보려 하지 말고, 작은 이익을 추구하지 말라. 빨리 성과를 보려하면 제대로 성과를 달성하지 못하고, 작은 이익을 추구하면 큰일이 이루어지지 않는다
이루려고 하는 일을 바라보는 시각에 대한 핵심적인 사상이 담겨 있는 격언이라고 생각된다. 조급하면 일을 쉽게 망칠 수 있다는
것은 다들 알고 있는 사실이다. 단지 격언으로 뿐만 아니라 경험적으로도 알고 있는 사실이다. 그런데 조급해지지 않기가 쉽지 않은
것 같다.
공자께서 말씀하셨다. 가난하면서 원망하지 않기는 어렵지만, 부자 이면서 교만하지 않기는 쉽다
프로젝트가 제대로 수행이 안되면, 서로 원망하게 마련이다. 책임을 떠넘기기도 한다. 이때문에 서로 상처를 입히고, 팀이
와해되기도 한다. 큰 프로젝트는 제대로 수행되기가 매우 어렵다. 특히 최근의 프로젝트들은 아주 작은 프로젝트라고 하더라도
입력되는 정보와 출력되는 정보가 명확하지 않기 때문에 욕심을 부리다가는 망해먹기 십상이다. 이런 이유로 애자일에
서의 (대략 한달 주기의)짧은 주기의 개발방법론등이 대안으로 제시한다. 한번에 완성된 제품을 만드는 대신, 기능을 최소화하고
입력과 출력을 제한한 중간 제품들을 만드는 식이다. 기능을 줄이고 입력과 출력을 제한하면, (완성된 단계가 아니라고 하더라도)
그 단계에서의 성공적인 수행 확률은 높아진다. 팀원들은 자신감을 얻게 되고 사기는 올라간다.
공자께서는 네 가지를 절대로 하지 않으셨다. 사사로운 뜻을 갖는일이 없으셨고, 기필코 해야 한다는 일이 없으셨으며, 무리하게 고집부리는 일도 없으셨고, 자신만을 내세우려는 일도 없으셨다.
프로젝트를 진행할때는 사사로이 하고 싶어하는걸 해서는 안될 것이다. 혼자진행하는 거라면 모르지만 서도 말이다. 하고싶은 것이
있다면 공적인 장으로 끌어올려서 공유해야 할 것이다. 기필코 해야 한다는 일이 없다는 것은 일함에 있어서 융통성을 가져야 한다는
것을 의미할 것이다. 이 바닥은 하나의 문제를 해결하는데 있어서 하나의 해결책만 있는게 아니다. 다양한 해결책이 있다. 때때로
다른 사람의 해결책이 자신의 것보다 못하다고 생각되더라도, 그 방법이 크게 잘못된게 아니라면 시시콜콜하게 소숫점까지 따질 필요는
없다고 나는 생각한다.
현대 자본주의 사회에서 살아남기 위한 덕목은 스피드와 경쟁력, 효율성이다. 이를 달성하기 위해서 시간과 공간을 집적시키길 원한다. 때로 인간다운 삶을 포기해야 한다. 이러한 현실에 비추어 유교의
가르침은 고리타분하고 비현실적이라는 느낌을 줄 수 있다. 욕심 없이 유유자적하면서 살 것이라면 모르지만 치열한 경쟁 사회에서
살아가기위한 지침으로 삼기엔 적당하지 않다고 생각되어지기 때문이다. 아름답지만 현실적이지 않은 가르침이라고나 할까 ?
시간과 공간을 집적시켜서 효율을 극대화 시키고 그것으로 이윤을 창출했던 산업시대에는 확실히 유교의 느긋함, 길게 보기, 사람 중심으로 보기, 결과 보다는 과정이
런건 사치로 여겨졌을 지도 모르겠다. 정보화,인터넷 시대인 지금 이러한 인식이 변하고 있다. 소프트웨어 업계의 여러가지 새로운
개방방법론들은 산업시대의 것들과는 분명히 다르며, 동양적사상을 오히려 따르려 하고 있음을 느낄 수 있다.
공자님의 격언을 보면 일관되게 일을 함에 있어서 소소한 것에 크게 신경쓰지 말라라고 하신다. 그게 해야할 업무이건 실수이건 간에 말이다. 큰것을 해결하면, 작은 것은 알아서 해결되는 경우가 많기 때문이다. 작은 것들에 신경을 쓰는 가장 흔한 이유는 잠깐이면 끝낼 수 있는 것 아니냐. 내가하면 5분안에 끝낼 수 있는데..라는 생각 때문인 것 같다. 큰일을 해결하면 작은일들도 해결되지만 작은일들이 모이면 큰일이 된다. 네버엔딩 프로젝트가 될 수도 있다. 인내와 믿음이 있어야 가능한 일이다. :::

음.. 완성된 문서가 아닙니다. 문서는 wiki 를 통해서 계속 수정/보완해나갈 생각입니다.
1 문서정보
1.1 작성자 정보
- 최초 작성자: mwyun(멍)
- 이래저래 수정한 사람 : yundream
2 객체지향
어디에선가 OO에 대응되어서 사용되는 객체지향자체가
잘못된 번역의 결과물이란걸 읽은 기억이 있다. 그러나 이게 번역이 잘못되든 되지 않았던간에 의미를 전달하는데 별 지장이 없고,
현재 표준적인 용어로 사용하고 있으므로 당분간은(혹은 매우 오랫동안) 객체지향이라는 단어를 사용하도록 하겠다.
최초의 근대적 기계의 개념을 담고 있는 기계의 제작은 아마도 고대 그리스시대로 올라갈듯 하다. 아리스토텔레스는 전쟁에서 사용될 수 있는 기계를 만들었으며, 실제 전차(현대적 개념의 탱크)도 설계했던 것으로 알려진다.
이후에 만들어진 기계는 뭐 사실은 고만고만한 기계였는데 이들 기계는 주로 물리력을 이용해서 "물건을" 옮기는 일을 하였다.
바퀴와 기어들로 이루어져 있으며 제어하기 위해서 인간이나 동물의 물리력을 필요로 했으며 얼마나 많은 일을 할 수 있는지를
나타내는 단위로 ' 마력을 사용했다.
그러다가 컴퓨터라
는 기존의 기계의 개념과는 매우 다른 기계가 만들어진다. 이 기계는 전자를 이용하는데, 특히 정보를 처리하는데 효과적으로
만들어진 기계였다. 얼마나 많은 정보를 처리할 수 있느냐로 성능을 나타내며 단위로 Hz(헤르쯔)를 사용한다.
컴퓨터라는 기계를를 제어하는 데에는 물리력 대신, 소프트웨어라고 불리우는 프로그램을 사용하게 된다. 우리 개발자는 컴퓨터 언어를 이용해서 컴퓨터를 제어하는 프로그램을 만드는 일을 한다.
컴퓨터는 정보를 처리함에 있어서 획기적인 기계이긴 했지만 아날로그 기계와는 달리 상태가 참과 거짓으로 표현되는 한계를 가지고 있었다. 참과, 거짓으로 정보분석이 진행되는 논리연산에는 효율적이였지만 아날로그 적인 실세계의 다른 정보들을 처리하기에는 그다지 효율적이지 못하다. 초기에는 컴퓨터의 사용용도가 한정적이였으므로 참, 거짓을 잘 이용하는 정도로 대부분의 일을 처리할 수 있었다. 프로그래밍언어 역시 이러하였다. 기계어, 어셈블리어, C(이론이 있을 수 있겠다) 등이 그러한 부류에 속한다.
참과 거짓에 기초를 둔 논리연산은 어떤 일련의 순서를 따르면서
정보를 처리하도록 되어 있다. 컨테이너 벨트를 이용해서 물건을 처리하는 것으로 보면 될 것이다. 컨테이너 벨트는 물건과 물건을
처리하는 프로세스가 분리되어 있는데, 컴퓨터 역시 데이터와 데이터를 처리하는 방법이
분리되어 있다. 이러한 방식은 복잡하지않은 정보를 처리할때는 효율적이지만 가계/기업경영/문서작성/음악재성/공장제어/게임에서와
같이 정보와 정보가 상호연관되어서 복잡하게 얽혀있는 경우에는 효율이 극히 떨어지게 된다. 수백개의 컨테이너 벨트가 만들어져
있는데, 필요에 따라서 이들 각 컨테이너를 서로 연결시켜서 데이터를 처리해야할 경우를 생각해보면 될것이다. 입력과 출력이 매우
명확한 제조업에서야 컨테이너벨트를 재배열해야 하는 일이 그다지 필요 없겠지만 소프트웨어 개발영역은 그렇지 않다. 따라서
소프트웨어를 개발하고 유지하고 보수하는데 많은 비용이 들게 된다.
그래서 만들어진게 "객체지향 프로그래밍"으로 컴퓨터가 데이터와 데이터의 처리과정을 분리시켜서 생각하는걸 하나의 객체로 보고 처리하도록 만들어진 방법론이다. 이 방법론을 이용해서 코드의 재사용성, 유지/보수성을 높이고자 하게 된다.
간단히 말하자면 객체는 주변에서 볼 수 있는 모든 (관찰되어지는)사물이다. 삽살개, 호랑이, 세포, 사람.. 전부다 객체다.
또한 눈에 보이는 구체적인 것 뿐만 아니라 경제, 국가, 시장 같은 눈에 보이지 않는 것도 객체라고 한다. 모든 것이 객체다!!! 단순명료하긴 하지만 너무 포괄적인 것 같으니 객체의 특징에 대해서 정리해볼 필요가 있을 것 같다.
객체는 내면과 내면을 감싸는 외피를 가진다. 세포라는 객체는 세포내용물질과 이들을 감싸는 외피로 구성이 된다. 관찰자에게 보이는
것은 외피가 된다. 내용물들과 내용물들이 상호작용하는 과정은 관찰자에게 감추어진다. 이렇게 내면을 감추는 외피를 가지는 것을 추상이라고 하는데, 이 추상은 객체가 가지는 대표적인 특징이다. 여기에 따르면 외피를 가지지 않는 것은 객체라고 할 수가 없다. 외피가 중요한 이유는 주변의 다른 사물과 구분되는 표면이 있어야 관찰자에게 독립적인 사물로 보여질 수 있기 때문이다. 표면은 경계라고 해도 좋을 것이다.
경제나 국가와 같은 것들도 인간은 객체라고 본다. 물리적인 외피를 가지지 않지만 인간의 인식하에서 경제는 경계를 가지고 있기
때문이다. 경계를 가지고 있으므로 관찰자인 인간은 경제를 관찰하고 분석할 수 있다. 여기에서 어떤 대상이 객체로 보이느냐 아니냐 하는 것은 상대적일 수 있음을 알 수 있다. 경제관념이 없는 지역의 사람들에게는 경제는 관찰할 수 있는 대상이 아니기 때문이다.
객체는 객체를 포함할 수 있다. 치아와나 셰퍼드는 객체다. 여기에서 더 나아가 이들 치아와나 셰퍼드를 통칭하는 개도 객체가 될 수 있다. 개는 치아와와 셰퍼드와 같은 객체의 공통적인 특징을 분석해서 인간의 지성이 만들어낸 가상의 개념이지만 고양이라는 다른 개념과 구분되는 외피를 가지고 있으므로 객체라고 할 수 있다. 개라는 객체는 치아와, 셰퍼드 객체를 포함한다. 이러한 객체의 속성을 이용하면 객체의 계층적- Hierarchy - 구조를 만들 수 있다. 이것은 복잡한 자연현상을 단순화 시켜서 인식할 수 있도록 도와준다. 대표적인 예가 종,속,과,목,강,문,계일 것이다.
객체는 주변환경 혹은 다른 객체와 상호작용한다. 생물의 경우 상호작용은 감각기관을 통해서 내부로 정보를 받아들인 다음 이를
처리하고 운동기관을 통해서 다른 객체를 조작한는 형식으로 이루어진다. 개가 위협적으로 달려들면 눈으로 이 정보를 받아들여서
처리한다음 다리근육을 움직여서 달아나거나 혹은 온몸을 이용해서 싸우거나 하는 식이다. 이러한 상호작용은 경제와 같은 구체적인 형태를 가지지 않은 객체에도 적용된다. 경제의 경우에는 신문, 뉴스, 주식매입, 은행업무등을 통해서 상호작용할 것이다.
이상에서 객체의 다음과 같은 특징을 뽑아낼 수 있을 것 이다.
- 객체는 내면과 내면을 감싸는 외피를 가진다.
- 내면은 외피 내부로 숨겨지며 이를 추상이라고 한다.
- 객체는 외피를 가짐으로써 주변사물과 독립적으로 구분될 수 있다.
- 객체는 외피를 가짐으로써 관찰대상이 될 수 있다.
- 구체적인 형태를 가지지 않는 것들 - 경제, 국가 - 도 객체가 될 수 있다.
- 객체에 대한 정의는 상대적이다.
- 객체는 객체를 포함할 수 있다.
위의 객체에 대한 내용은 다분히 철학적, 다른말로 말장난으로 보일 수 있을 것 같다. 그러나 이러한 특징은 컴퓨터 영역에서의 Object-orinted Programming 에도 그대로 나타난다.
모든 사물을 객체로 바라보는 주의는 실증주의와 경험주의에 바탕한 현대적인 과학의 바탕이 된다. 즉 인간의 오감과 상호작용해서 분석되어진 정보를 오랜시간 분석해서 - 즉 경험을 통하여 - 보편적인 지식으로 만드는 과학적사고 방식 만들어냈다.
과학적 사고는 상호작용 가능한 객체를 대상으로 이루어진다. 이런 의미에서 종교는 과학과 다른 길을 가게 된다. 신과 상호작용할
수는 없는 노릇이기 때문이다. 상호작용할 수 없는 건 객체가 아니다. 언젠가 신과 제대로 상호작용할 수 있는 어떠한 방법을
찾아낸다면 종교도 과학이 될 수는 있겠지만 말이다. 아 물론 지금도 신도들은 기도를 통해서 신과 상호작용 한다고 하지만
상호작용의 결과를 보여주지 않으니, 분석불가가 된다. 입력은 있는데 출력은 없는 상태라고나 할까.
신을 직접 입증하는게 불가능하다고 생각이 되자, 그들의 성서에 적혀있는 신화적 내용이 신화가 아닌 사실임을 증명하는 것으로 신이
있음을 간접적으로 증명하고자 하는 시도가 있었다. 신화는 어떤 부족의 역사를 담고 있는 경우가 많고, 역사는 과학적 탐구가
가능한 영역이니 말이다. 이것을 창조과학이라고 한다.
그러나 창조과학이 의미가 있을지에 대해서는 회의적이다. 설사 역사적 사실이 입증되더라도
말이다. 신화속의 도시로만 알려졌던 트로이가 발견이 되고, 아킬레우스가 실제 존재하던 인물이였음이 증명되었다고 해서,
아킬레우스가 신의 아들이고 트로이 전쟁을 신들이 배후조정했다는 증거가 되는건 전혀 아니기 때문이다. 종교는 그냥 믿음의 영역으로
두면 되는 것이다.
때때로 기술이 발전함에 따라서 너무터무니 없어서 신화와 같은 것으로 생각되던게 상호작용 가능한 과학적 탐구가능한 객체가
되기도 한다. 4차원이네 10차원이네 하는 것들은 과거에는 터무니 없는 것이였으나 입자가속기의 등장으로 그 실체를 거의 규명할
수 있게 된게 그 예가 될 것이다. 그렇다고 해서 신과 대화가능한 기계를 만들어 낼 수 있을까 ?? 뭐, 이벤트호라이즌호는
강력한 중력발생기를 이용해서 뜬금없는 지옥도 다녀오긴 했지만 이건 어디까지나 영화의 이야기고.
2.2 추상(抽象)화 와 추상화 과정
위에서 객체는 내부를 숨기는 외피를 가진다고 했다. 이것을 추상이라고 하는데, 객체의 가장 큰 특징중 하나다. 이 추상에 대해서 알아보도록 하자.
현대적인 추상개념을 체계화 한것은 플라톤으로 생각된다. 플라톤은 이데아라는 것을 주창하였다. 세상은 이데아라는 완전한 세계에 있는 원본틀의 그림자로 생겨난 것이다라는게 이데아의 핵심이다. 원본의 그림자이니 세상은 언제나 불완전할 수 밖에 없다. 이데아는 완전한세계, 영혼으로 볼 수 있는 세계라는게 플라톤의 생각이었다.
개를 예로 들어보자. 개를 본적이 있는가 ? 뜬금없는 말 같지만 개그 자체를 본적은 없을 것이다. 왜냐하면 개는 물리적인 대상을 가리키는게 아니기 때문이다. 우리는 삽살개, 치아와, 셰퍼드를 볼 수 있지만 개를 본적은 없다. 플라톤이 주장하는 바에 따르면 개가 바로 치아와 삽살개 셰퍼드등 이 세계에 존재하는 여러가지 개의 성질을 가지는 것들의 유일한 원본이다. 이 유일한 개의 그림자가 바로 우리가 볼수 있는 치아와 인 것이다. 이데아는 우리가 사는 세계보다 차원이 높은 세계이므로 우리는 단지 개의 그림자만을 볼 수 있을 뿐이다.
이처럼 차원이 낮아지면 얻을 수 있는 장점이 있다. 그것은 수많은 개의 성질을 가지는 객체를 만들어 낼 수 있다는 점이다. 앞서 이 세상에 물리적으로 존재하는 개들은 이데아 개의 그림자라고 했는데, 그림자는 그 모습이 완벽하지 못하다. 광원의 거리와 흔들림에 따라서 찌그러지기도 하고 커지거나 작아지거나 할 수 있다. 개는 하나이지만 수많은 개들이 존재하는 이유이다.
플라톤이 이데아를 생각해 냈던 것을 반대로 하면 그게 추상화가 된다. 즉 멍멍 소리를 내고, 꼬리를 흔들며, 다리가 4개고, 코가 뾰족한 특징을 가지는동물들을 개라고 정의 하는 것이다. 이렇게 해서 우리는 눈에 보이지 않는 개라는 새로운 상위 차원의 개념을 만들어내게 되었다.
추상화 과정이란 어떤 구체적인 사물로 부터 공통적인 속성을 찾아내어서 그것들을 포괄할 수 있는 상위의 포괄적 개념을 만들어내는 과정이다.
2.3 컴퓨터에서의 추상화
컴퓨터 언어역시 이러한 추상화 과정을 거친다. 가장 간단한 어셈블리는 이를테면 생명체의 바이러스라고 할만한데, 가장 간단한
추상화 과정을 거친다. 기계어와 거의 일대일 대응을 하는데, 다만 좀더 이해하기 쉽게 만들도록 "한단계"의 추상화 과정을 거쳤을
뿐이다. 포트란, 베이직, C와 같은 언어들은 어셈블리어에 비해서 더욱 많은 추상화를 이루고 있으며, 여러가지 면에서 크게 발전되었다.
그러나 이들 언어는 컴퓨터 기계가 만들어 졌던때의 그철학을 그대로 따르고 있어서 실제 생활에서 발생할 수 있는 다양한 문제를
푸는데 있어서 절차지향적인 방법을 따른다. 이건 어셈블리어 뿐만아니라, 포트란, 베이직, C 모두에 포함된다. 절차지향적이란
컨테이너 벨트라고 생각하면 된다. 재료를 집어 넣고 컨테이너 벨트에 집어 넣으면 최종적으로 물건이 튀어 나오는 것이다. 풀어야할
문제가 복잡해 질 수록 이런 절차지향적 방법으로는 한계에 부딪히게 된다. 즉 개발모델이 문제다.
여기에서 한계란.. 문제를 풀 수 없다라는 것이 아니고, 효율적으로 풀수 없으며
단지 푸는 것 뿐만 아니라, 유지하고 보수하고 확장시키는데 기존 방법으로는
많은 시간과 비용이 소비될 확률이 많다는 것이다.
그래서 만들어진 개발 모델이 객체지향 모델이다. 컨테이너 벨트 모형을 따르는 절차지향 개발 모델에서는 데이터와 데이터를 가공하기 위한 메서드(함수)가 서로 분리 되어 있다. 데이터가 계속 흘러가고 중간에 함수가 있어서 가공하고 다시 다음 함수로 넘겨주는 방식이다.
반면 객체지향 개발 모델에서는 데이터와 메서드를 분리하지 않고 하나의 공간에 둔다.
객체지향을 목표로 제작된 최초의 (성공적인) 언어로 Smalltalk라는 언어가 있다. Java도 이 언어를 기초래 햇 만들어
졌는데, 객체지향을 위한 기본적인 노선이 정립된 언어다. 객제지향 언어라고 한다면 보통 아래의 5가지의 요소를 만족시키는 특성을
지원할 수 있어야 한다.
- 모든 것은 객체다 : 간단하게 생각해서 객체는 데이터와 데이터를 처리하기 위한 메서드를 함께 가지는 모든 것을 말한다. 이론적으로 객체를 이용하면 모든 사물을 완벽하게 구현할 수 있다. (자동차, 개, 건물, 은행 서비스 ..)
- 프로그램은 객체사이의 메시지 전달을 이용해서 통신한다 : 두명의 사람(객체)가
상호작용하기 위해서 대화를 하는 것과 마찬가지다. 프로그램의 경우 두개의 객체(보통 클래스, 패키지라고 한다)를 연결하기 위한
메시지 전달 클래스를 만들 수도 있을 것이다. 사람과 사람이 대화를 하는데 중간에 매질(공기)이라는 객체가 대화를 전송하는 것과
같은 이치다.
- 각각의 객체는 자신만의 메모리를 가진다 : 객체는 데이터와 메서드를 하나의 공간에서 다루며, 객체는 다른 객체와 독립적으로 행동한다. 고로 자신만의 데이터를 저장하기 위한 공간을 가질 수 있어야 한다.
- 모든 객체는 이름을 가진다 : 각 객체는 독립적으로 구분될 수 있어야 한다. 그러기 위해서 이름(type)을 부여한다. 각각의 사람을 구별하기 위해서 "이름"을 부여하는 것과 마찬가지다.
- 동일한 특성의 객체는 동일한 메시지를 사용한다 : A라는 사람과 B라는 사람은 독립적인
객체이지만, 또한 "사람"이라는 동일한 특성의 객체이기도 하다. 이들 객체간의 대화를 위해서는 당연하지만 같은 언어가 사용되어야
할 것이다. 사람과 개의 경우에는 대화가 되지 않을 것이다. 프로그램에서도 동일한 특성의 객체들은 동일한 메시지를 이용해야
한다.
2.4 추상화를 통해 얻는 이득
자동차를 생각해보자. 자동차는 인류가 개발한 육상이동 수단중 가장 고도로 추상화된 기계다. 자체에 발전,공급,저장,통신,제어 시설을 갖춘 소형 공장이라고 할만하다.
그러나 운전자가 이러한 모든내용을 알아야지만 자동차를 이용할 수 있는 건 아니다. 대부분의 기능들은 추상화(숨겨져)있으며, 사용자는 단지 핸들과, 브레이크, 악셀레이터와 몇개의 계기판을 볼수 있으면 운전이 가능하다.
복잡한 내부 구현을 숨김으로써 사용자는 이것 저것 신경쓸 필요 없이, 제공되는 몇개의 인터페이스만으로 사용이 가능하다. 이게 추상화가 가져다 주는 첫번째 이득이다.
자동차가 처음 나왔던게 19세기 말이였던 것 같다. 그러나 성능상의 차이는 있겠지만 100년이 지난 지금도 자동차의 기본적인
운전방법은 거의 변함이 없다. 그때나 지금이나 여전히 운전자는 핸들, 브레이크, 악셀레이터 이 3가지를 이용해서 자동차를
제어한다. 이러한것 자동차의 구현을 "추상화"함으로 가능하다.
즉 구현과 인터페이스를 분리시켜줌으로 (최초에 인터페이스만 잘 설계한다면)기능이 대폭업그레이드 되더라도 사용자는 이것에 신경쓸필요 없이 기존의 운전기술을 그대로 사용할 수 있게 된다.
프로그램개발에 있어서도 이러한 이득을 그대로 이용할 수 있다. 추상화를(잘) 시키게 되면 인터페이스와 구현을 구분시켜 줌으로써
일반 프로그램개발을 할적에 세부저인 복잡한 구조를 신경쓸 필요 없이 제공되는 몇개의 인터페이스만을 이용해서 필요한 일을 할 수
있다. 구현을 업그레이드 시켜야할 경우에도 개발자는 여기에 대해서 신경쓸 필요가 없게 된다.
간단하게 생각하자면 우리가 프로그래밍을 위해서 사용하는 open(2), write(2)같은 함수역시 추상화의 결과물이다. 우리는 open(2)의 내부구조가 어떻게 되어있는지 신경쓰지 않고도 잘 쓸 수 있다.
2.5 객체는 인터페이스를 가진다.
객체에 대해서 깊은 사고를 한 최초의 철학자는 (보통)아리스토 텔레스로 알려져 있다.그는 "the class of fishes
and the class of birds"라고 실존하는 모든 것들을 객체로 분류했다. 객체는 일반적으로 유일하며, 각 객체는
고유의 특징과 행동특징을 가지는 것으로 정의할 수 있다. 클래스란 이러한 객체의 고유 특성과 행동특징을 함께 묶어놓은 개념이다.
하나의 클래스는 여러개의 객체를 포함할 수도 있다. 새라는 클래스에 참새 1, 참새 2, 제비, 할미새와 같은 객체가 포함될 수
있는 것과 마찬가지다.
클래스(class)를 처음 도입한 객체지향 언어는 Simula-67 이다.
Simula는 그 이름에서 느낄 수 있는것 처럼 어떤 상황을 "시뮬레이션"하기 위한 용도로 작성되었으며 bank teller problem과 같은 문제를 해결하기 위해서 사용되었다. 여기에 상담원, 고객, 트랜잭션, 계정, 돈등과 같은 많은 요소들이 있다. 이러한 요소들은 "은행업무"라는 작업을 달성하기 위해서 상호통신하면서 일종의 그룹처
럼 움직인다. 그렇다면 이들 요소를 하나의 클래스로 묶어서 처리하게 된다면 좀더 현실에 가깝게 상황을 시뮬레이션 할 수 있을
것이다. 즉 요소의 유기적인 모임인 클래스가 또하나의 데이터가 되는 것이다. 각 요소는 하나의 클래스 안에서 유지적으로
움직인다. 예를 들어 고객은 상담원과 상담을 하고 자신의 계정을 통해서 저금을 하거나 돈을 찾거나 또는 다른일을 할 수 있다.
만약 새로운 고객이 은행창구에 들어온다면 새로운 "은행업무-1" 객체가 생성될 것이다.
이처럼 클래스라는 개념은 어떤 상황을 시뮬레이션 하기에 적당한 개념이라는 것을 알 수 있다. 이론적으로 클래스를 이용하면 모든
상황에 대한 시뮬레이션이 가능하다. 클래스에 있는 각각의 요소들은 어떤 문제를 풀기 위해서 존재한다. 즉 객체지향 프로그래밍이라
함은 어떠한 동일 문제해결영역에 있는 여러 요소들을 제어함으로써 문제를 해결하기 위한 개발철학이라고 할 수 있다. 대부분의
객체지향 언어에서 문제해결영역은 보통 class라는 키워드로 표현된다.
지금까지 클래스에 대한 대략적인 내용을 살펴보았는데, 지극히 추상적이고 철학적이라서 어떻게 써먹을 수 있을지 감이 잡히지 않을 수 있을 것 같다. 구체적인 이해를 돕기 위해서 전구에 대한 제어를 시뮬레이션 해보기로 하겠다. 문제영역은 빛의 조절이며 이 문제를 해결하기 위해서 켜기, 끄기, 밝게하기, 어둡게 하기라는 인터페이스 들이 필요함을 알 수 있다. 이들 인터페이스를 통해서 다루는 요소(데이터)는 빛이 될 것이다.

위의 클래스를 보면 빛을
조절하기 위해서 4개의 인터페이스가 사용자(프로그래머)에게 제공되어짐을 알 수 있다. 프로그래머는 4개의 인터페이스를 이용해서
필요한 모든일을 할 수 있는데 인터페이스를 통해서 실제 내부적으로 어떠한 일이 일어나는 지와 내부의 데이터가 숨어(추상화)되어
있음을 알 수 있다. 사용자는 각 인터페이스를 조절해서 필요한 일을 수행하게 된다.
여기에서 클래스의 이름은 Light라고 했다. 자 이제 여러분이 전구를 하나 샀다고 하면 이로서 It이라는 새로운 객체를 생성된 것이다. 여러개의 전구가 필요할 수 있는데, 그럴 때마다 서로 다른 이름을 가지는 객체를 생성시키면 된다. It객체는 클래스 Light를 참조해서 생성된 객체이며 new라는 키워드를 통해서 생성된다(돈주고 전구하나 사는 것과 동일하다). 여기에서 우리는 클래스와 객체의 이름간에 연결이 있음을 알 수 있다.
위의 같이 클래스와 객체간 연관관계를 연결하는 다이어그램(diagram)형식의 구성도를 그릴 수 있을 것인데, UML(Unified
Modeling Language)라는 도구를 이용해서 그릴 수 있다. 위의 경우는 클래스와 객체의 가장 단순한 예이지만
객체자체가 클래스가 될 수 있고, 상속등이 일어날 수 있으므로 실제로는 꽤나 복잡한 구성도가 만들어지게 된다. UML은 그
자체가 하나의 학습분야이므로 여기에서는 자세히 다루지 않을 것이다. 이런것이 있다는 정도만 이해하고 넘어가도록 하자.
2.6 객체는 서비스를 제공한다.
뻔한 얘기다. 은행업무-1객체는 고객에게 은행서비스를 제공하기 위해서, It객체는 밝게 비춰주는 서비스를 제공하기 위해서 존재한다.
3 OOP (Object-Oriented Programming) 개론
이 글은 제가 오래전 잡지에서 본 강좌를 타이핑하여 파일로 저장해둔 것을 올린 것입니다.
아쉽게도 잡지명이나 저자 이름은 오래된지라 기억이 나지 않지만 전문을 올렸으니 잘 읽어보시기 바랍니다.
3.1 Object-Oriented Programming의 등장
3.1.1 소프트웨어 위기 (Software Crisis)
컴퓨터가 출현하고 그 기능이 발달함에 따라 우리들은 그것을 사용하여 보다 편리하고 윤택한 생활 - 정말 윤택하게 되었는지
아닌지에 대한 언급은 하지 않도록 하겠다 - 을 하게 되었다. 그에 따라 소프트웨어의 수요가 기하급수적으로 증가하게된다. 결국
공급이 수요를 따라가지 못하는 상태에 이르게 된다. 하드웨어의 발전은 눈부시도록 놀라운데 그에 비하면 소프트웨어의 발전은 그
발치에도 미치지 못하고 있는 것이다. 이러한 위기상황 속에서 이를 극복하고자 하는 노력을 구체적인 방법론으로 표현한 것이
소프트웨어 공학 (SE : Software Engineering)인데, Object-Oriented Programming(Paradigm)도 바로 이 SE의 한 범주에 속한다고 할 수 있겠다. 집채만한 공룡이 메추리알 크기의 뇌를 가지고 있는 상태라고 볼 수 있을 것이다.
3.1.2 소프트웨어의 구성 방법의 변천
초창기에는 모든 소프트웨어를 단지 하나의 Procedure로 만들어 냈다. 그러나 많은 시간과 여러 사람의 노력이 필요한 큰
시스템을 구축하려고 할 때에 이런 방법은 적절하지 못하다. 그래서 큰 프로그램을 각 기능별로 여러개의 Subroutine으로 나누어(Functional Decomposition) 독립적인 부분으로 만들어(Modularization)
여러사람에게 할당하고, 각각의 모듈이 완성된 후에는 그것들을 서로 짜맞추어 하나의 시스템으로 완성하는 방법을 사용하게 된다.
이것을 Modular Programming이라고 한다. 이 Modular Programming과 함께 몇몇 규칙들을 적용하여
Structured Paradigm이라는 소프트웨어 구성방법이 생겨나게 되었으며, 지금까지도 널리 사용되고 있다.
3.1.3 Structured 방법의 문제점
기존의 Structured 방법은 처리(Process)를 중심으로 하고 있다. 바로 이점이 문제가 된다. 데이타(Data)
는 단지 강의실에서의 칠판처럼 필요할때마다 썼다 지웠다하는 보조 수단으로 여겨 그다지 중요시하지 않게 생각했다. 데이터를 독립된
단위로 보는 이러한 시각은 처리해야할 데이터의 절대적인 양자체가 적었을때는 크게 문제가 되지 않겠지만, 요즘처럼 다루어야 하는
데이터의 기본단위가 기가가 되는 경우에는 문제가 된다. 많은 데이타를 공유해야만하고, 원하는 데이타를 여기저기 마구 불러 사용하는 상황은 Modular Programming의 원리를 어기게 되었고 따라서 모듈의 재활용성(Reusablity)이 떨어지게 된 것이다. DBMS(DataBase Management System)를 사용하여 이런 문제를 다소 해결할 수는 있으나 이로서는 충분하지 않다.
3.1.4 Object-Oriented Paradigm의 등장
프로그램의 재활용성을 높이기 위해서는 Modular Programming, 이를 위해서는 Procedure뿐만이 아니라 데이타도 모듈화 되어야 한다는 방법론이 등장했으며 이것이 Object-Oriented Paradigm의 중요한 기본 요소가 되었다. 1960년대에 등장한 Simula는 현실세계를 Simulation하는 것을 주목적으로 하는 프로그래밍 언어였는데, 이 프로그램에 도입된 프로그래밍 개념이 바로 Object-Oriented Paradigm의 효시가 되었다.
3.2 OOP의 기본개념
Object는 데이타와 이와 관련된 Procedure를 한데 묶어 표현한 소프트웨어 패키지이다. 이는현실세계가 처리중심이 아닌 사물(객체 : Object)중심으로 이루어졌다는데에 바탕을 둔 것이다. 세포(Cell)
를 예로 들어 생각해 보자. 세포는 핵, 미토콘드리아, 세포질, 세포막 등으로 이루어 졌는데, 이러한 세포의 구성 요소들에게는
각각의 역활이 주어져 있다. 그러나 기관의 입장에서 살펴면, 세포의 구성 요소들이 어떠한 일들을 하는지는 그다지 중요한 사실이
아니다. 단지 단백질이나 무기질을 세포내로 전달해 주면, 세포는 그것들을 가지고 자신의 임무만을 수행하면 되는 것이다. 세포내에
어떠한 구성원들이 있는지는 알 필요도 없고, 단지 세포 그 자체로서만 인식되면 충분한 것이다. Object도 이와 마찬가지로
생각하면 쉽게 이해가 갈 것이다.
3.2.2 Abstract Data Type & Data Abstraction
프로그래머가 기존의 Data Type을 이용 - 조합 - 하여 정의한 새로운 Data Type을 Abstract Data
Type이라고 하며, 이것을 Data Abstraction(데이터 추상화)이라한다. 이때 일반적으로 새로운 데이터와 그 데이터에
대한 연산까지 함께 묶어서 - 즉 객체단위로 - 정의한다. 이렇게 함으로써 사람의 생각을 한단계 높여, 구체적인 Low-Level(Primary) Data와 연산이 아닌, 추상화된 Data와 연산을 다룰 수 있게 된다. 이 Data Abstration은 복잡한 데이타(Complex Data)를 다룰때에 효과적이다. 실제로 "Program = Level of Abstraction"이라는 관점도 있다. 가장 간단한 형태의 데이터 추상은 구조체일 것이다.
3.2.3 Encapsulation
Data Abstraction를 이용하면 Encapsulation을 달성할 수 있다.
필요한 데이타와 Procedure를 모아 캡슐에 담는 것에 착안하여이렇게 이름을 붙인 것이다. 실제로 이
Encapsulation으로 인해 생겨난 결과가 Object이다. 예를 들면, Nucleus(핵),
Mitochondria(미토콘드리아), Membrane(세포막)등의 변수들과 그와 관계된 함수들을 Cell(세포)이란
object내에 정의해 놓은 것이다. 이렇게 함으로써 우리들은 자세한 부분까지 신경을 쓸 필요가 없고 단지 세포라는
Object와 Object로의 입출력 데이터만 생각하면 된다.
3.2.4 Infomation Hiding
Encapsulation으로 인해 내부의 데이타는 외부로 부터 고립되었다. 데이타는 필요한 때에 단지 외부로부터의
Message에 의해서만 접근되어질 수 있는데, 이러한 것을 Information Hiding(정보 은닉)이라 한다. 만약
Object내의일부분을 수정하였다고 해도 그 변화는 단지 Object내에서만 영향을 끼치고, 이로 인하여 완전히 모듈화가
이루어지는 것이다.
3.2.5 Composite Object
한 Object가 다른 Object를 포함할 수 있는데 이를 Composite Object라 한다. 이렇게 함으로써 포함된
Object를 새로운 Object의 한 부분으로 단순화시킬 수 있고, 그에 대한 자세한 내용을 알 필요도 없으며 많은 주의를
기울일 필요도 없이 사용할 수 있다. 미토콘드리아와 세포와의 관계를 생각하면 될 것이다.
Message는 Object사이의 소통을 가능하게 하는 방법이다. Message는 Receiver, Method,
Parameter의 세부분으로 구성되어 있는데, 예를 들어 "Car go: 20" (이것은 Smalltalk에서 사용되는
표현이다. C++에서는 Car.go(20)의 형태이며, Object-Oriented 방법을 지원하는 Programming
Language에서 Message의 구성요소들의 순서는 일반적으로 같은 경우가 많다.)라는 Message에서 Car는
Receiver이고 go:는 Method, 20은 Parameter이다. 쉽게 알수 있듯이 이 Receiver는 대상이
되는(Message를 수신하는) object의 이름이고,go:는 Car Object내에 정의된 Procedure(또는
Function)인데 Object-Oriented방법에서는 Method라고 부른다. 20은 Method의 Parameter이다. Parameter는 경우에 따라 필요하지 않을 수도 있다. Object는 Message를 통해서만 접근될 수 있다.
3.2.7 Overloading
같은 Method이름에 하나 이상의 의미를 부여하는 것을 Overloading이라 한다. 예를 들어 Circle,
Triangle, Rectangle 이라는 세 Object는 도형이라는 공통점을 가지고 있다. 이러한 도형을 그리기 위해
Method를 정의한다고 하자. 세 도형을 그리는 방법은 확연하게 다르다. 그러므로 각각 CircleDraw,
TriangleDraw, RectangleDraw라는 별개의 이름으로 된 Method를 만들어야 하는데, 이러한 불편함을 없애기
위해서 Draw라는 한개의 공통된 Method이름을 사용한 세개의 method를 만들어 각각의 object에 정의한다. 단지
어떤 Receiver에게 Message가 수신되는가에 따라 세가지의 Method(Draw)
중 하나가 결정되어 사용되는 것이다. 그러므로 "Circle Draw:10"이라는 Message가 주어지면 반지름이 10인 원을
그릴 것이고, "Rectangle Draw: 30 20"인 Message로는 가로 30, 세로 20인 직사각형을 그 것이다.
3.2.8 Overloading의 장점
예를 들어 Shape라는 Object가 있다고 가정해 보자. 이 Object는 위에서 예로 든 세가지의 Object중 하나의
값을 가질 수 있다고 하면, Program내에서 이 Shpae를 그린다고 할 때 기존의 방법으로 하려면 세가지의 선택문으로
표현되어야 한다.
if Shape = Circle then CircleDraw else if Shape = Triangle then TriangleDraw else RectangleDraw
이렇게 하게되면, Program내에서 Object에 대한 상세한 내용까지 Programmer가 알고 있어야 하므로
Programmer에게 부담이 된다. 나중에 Shape에 새로운 Object(예를 들면, Hexagon 같은)를 추가된면 역시
Program내에 수정이 가해진다. 그러나 Object-Oriented방법으로는 간단하게 "Shape Draw:라는 문장으로
충분하다. 새로운 object를 추가하더라도 Program을 수정할 필요 없으므로 확장성이 좋고, Program내에서
Object에 대한 자세한 내용을 알 필요가 없으므로 Information Hiding이 가능해 지며, 사용하기에도 편리하며,
이 모든 장점으로 인 Module화가 가능해진다.
3.2.9 Polymorphism
공통된 Interface를 사용하여 하나이상의 기능을 수행할 수 있는 것을 Polymorphism이라고 한다. 이것은
Overloading과 Overriding(특별한 형태의 Overlading)을 보다 일반적으로 일컫는 표현이다.
Class는 Method와 Attribute(속성)들을 포함하는 특정한 형태의 Object를 정의하는 틀(Template)
이다. 따라서 Class는 금형과 같이 수많은 복제품을 만들어 낼수 있으며, 이 복제품을 Instance라고 한다.
Instance는 단지 (Value)들 만을 포함하고 있으며, 따라서 이 Instance에 Method가 수신되면 Class에서
Method를 찾아 수행한다. 그러므로 'Object'는 Class의 Instance라 고 할 수 있다. 세포로 얘기하자면
어떠한 세포로도 분화 가능한 만능세포가 Class 쯤에 해당한다고 볼 수 있다. 만능세포는 자신이 위치하는 기관에 따라서 신경세포, 근육세포, 뉴런세포등 다양한 세포를 만들어 낸다.
3.2.11 SuperClass와 SubClass
한 Class가 다른 Class의 특정한 형태의 하나로 정의될 때 기존의 Class를 SuperClass, 새로운 Class를 SubClass라 한다.
3.2.12 Inheritence(상속)
SubClass는 SuperClass의 모든 것들을 상속 받을 수 있다. 즉, SuperClass의 모든 Method와 Attribute들을 별도의 정의없이 사용할 수 있다.
3.2.13 Class Hierarchy
Class Hierarchy란 Class들의 Tree모양의 구조를 말한다. 이것은 -이론적으로- 제한없이 중첩(Nesting)
될 수 있으며, Inheritance는 축적되어 아래 단계로 내려간다. 즉, 한 Class에서는 그 상위 Level에 있는 조상
Class의 모든 성질을 계승받을 수 있다. 이 Class Hierarchy는 정보와 정보를 다루기 위한 방법들을 전승할 수
있다는 장점을 가진다.
3.2.14 예외(exception)의 처리 : Overriding
앞의 예에서 Vehicle Class에 비행기를(Aircraft)
라는 SubClass를 첨가시킨다고 하자. Vehicle을 움직이게 하는 Method가 'go'라고 할때, go 신호를 보내면
일반적으로 시동을 걸고 Hand Break를 푼 후에 엑셀레이터를 밟아 앞으로 나아간다. 하지만 비행기는 자동차와 상당히
다르다. 스위치를 눌러 시동을 건 후, 여기저기 게기판을 만진 후에 하늘로 날아오른다. 그후에도 고도조절, 속도조절, 기류도
한번 살펴보고 건물이나 산과 부딕치지 않도록 조심하고...
실제 Class의 경우에 대해서 생각해보자. Method의 이름을 다른 것으로 바꿀 것인가? 그러면 일관성이 없어진다. 그렇다고
SuperClass인 Vehicls에서 'go'란 Method를 한단계 밑으로 끌어내려 정의한다면, 똑같은 내용을 Auto,
Truck, Bus의 세 Class에 정의해야 하므로 중복이 되어 비효울적이다. 이때는 SuperClass(Vehicls)에 있는 Method는 그대로 두고 SubClass(Aircraft)
에 'go'라는 Method를 재정의하는 것이다. 그러면 Message를 수신하는 Object가 어떤지에 따라서 적합한
Method가 선택되어 실행된다. 이렇게 SuperClass에 있는 Method의 이름으로 새롭게 Method를 재정의 하는것을
Overrding이라 한다.
3.2.15 Virtual Class(Abstract Class)
단지 구조적인 목적으로만 사용되기 위하여 설계된 Class를 말한다. 앞으로 사용될 기능들(Attribute,
Method)을 모아놓기만 하고 구체적인 구현은 나중으로 미루어, 다른 Class들의 Base Class로만 사용된다. 따라서
Virtual Class의 Instance는 존재할 수가 없다. Abstract Class라고도 하지만, Abstract
Data Type과의 혼동을 방지하기 하여 일반적으로 Virtual Class라고 한다.
3.2.16 Multiple Inheritance(다중 상속)
한 Class가 여러개의 SuperClass를 가질 수 있도록 하는 것을 말한다. '철강회사의 노동조합장'의 경우를 예로
들어보자, 그는 유능한 용접공이며 또한 회사의 업무를 관장하는 간부이기 하다. 단지 Single Inheritanc만이
가능하다고 하면
그림에서처럼 간부의 역활을 이중으로 정의해야 하므로 비효율적이다. 이때 Multiple Inheritance를 이용하면
효율적이다. 하지만 이때에 주의해야 할 사항이 있다. 같은 이름으로 정의된 Method가 각각의 SuperClass(용접공,
조합장)에 존재하면, 이때에는 어떤 SuperClass의 Method를 사용해야 할지 결정할 수가 없다. 즉, Conflict가
일어나게 되는 것이다.
Multiple Inheritance를 이용하면 이러한 문제를 해결할 수 있다. 그러나 함부러 마구 갖다붙이지 않도록 주의를
기울여야 한다. 중요하지 않은 곳에 오용되는 경우가 종종 있다. 위의 예에서 '조합장'의 경우를 생각해 보자. Multiple
Inheritance를 올바르게 사용한 것인가? 이전에는 용접공이었지만 조합장이 된 후에는 실제로 용접을 하지않고 회사의
업무만을 관리하게 되었다면 그때부터는 사실상 용접공이라고 할 수가 없다. 이러한 경우에는 용접공의 계승을 없애버려야 한다.
계승되는 SuperClass의 성질을 온전히 포함하고 있는지 살펴보는 것이 올바르게 Multiple Inheritance를
사용하고 있는지 여부의 판단 기준이 된다.
3.2.17 Class Hierarchy의 구성
제대로 된 Class Hierarchy를 구성하기 위해서는, 우선 나중에 쉽게 재활용될수 있도록 일반적인 목적으로 설계되어야
한다. 또한 이 Class Hierarchy는 현실세계를 잘 반영할 수 있어야 하며, Method는 가능한한 가장 높은 최상의
단계에서 정의되어야 중복을 줄일 수 있다.
3.3 Object-Oriented 방법을 이용한 Software의 구축
3.3.1 Reusability(재활용성)
Object-Oriented 방법의 가장 중요한 착안 사항이 바로 이 재활용성일 것이다. Reusable Module이 많이
마련되어 있다면 그것들을 이용하여 Software를 구축하면 보다 적은 노력만이 필요할 것이다. 실제로 Reusable
Module을 설계하는 데에는 설계, 분석의 과정을 거쳐야 하므로 설계상의 자세한 내용은 줄이고 개념적인 것만 살펴보자.
Reusable Module을 설계하는 것은 대게의 경우 필요한 것을 그때 그때 만들어 쓰는 것보다 더 많은 계획과 노력을 필요로 한다.
OOP의 핵심은 추상화에 있는데, 이 추상이라는 것은 다루고자하는
객체들의 공통된 속성을 뽑아내어서 일반화된 계층을 만들어 내는 행위다. 그러므로 다루어야 할 객체들과 주변환경에 대한 폭넓은
이해가 우선적으로 필요하다. 삽살개, 진돗개, 치아와 등에 대한 공통적인 특징들을 제대로 알고 있어야 비로서 개를 제대로 정의할 수 있는 것과 마찬가지다. 많은 시간이 필요할 수 밖에 없다.
이들 Reusable Module은 Class 를 중심으로 설계된다. 전에 언급한 Class의 장점들 - 현실세계를 잘 반영할 수 있으므로 인간의 생각을 표현하는데에 수월하고, 상속(Inheritance)
을 이용하여 확장이 쉬워지며, Polymophism을 적용하여 특별한 예외 경우를 잘 처리할 수 있는 점 등 - 이
Module을 설계하는데 꼭 맞게 적용되기 때문이다. Reusable Class는 필요한 것들을 직접 설계해서 얻을 수 있을
뿐만 아니라, Programming Language에서 제공되기도 하고, 때로는 상점에서 구입하는 것이 효율적일 때도 있다.
3.3.2 Object를 직접 사용한 Software의 구축
기존에 만들어진 Reusable Object를 모아 Software를 구축할 수 있다 하지만 이 방법은 필요로 하는
Object들을 모아 실제로 구동시키는 새로운 Object를 만들어야 하는데 불편함이 있다 (Program = Class
Libraries + Solution Classes). 물론 기존의 방법에 비하면 이 정도로도 훌륭하지만, 더 나은 방법이 있다.
3.3.3 Simulation
그 방법은 Class Library들을 모아 Modeling을 하는 것이다. 즉, 기존의 Class들을 이용하는
High-Level Object 까지도 미래의 필요에 대비하여 설계하는 것이다. 은행의 전산처리 System을 구축하는 것을
예로 들어보자. 여기에는 입출금 계산, 신용카드 결재, 각종 공과금 자동납부 등 여러가지 작업들이 필요할 것이다. 이때에
Class Library들을 이용하여 입출금 계산 System, 신용카드 결재 System, 공과금 자동납부 System 등을
미리 설계해 놓으면, 나중에는 단지 이것들을 끼워 맞추기만 하면 되므로 Class Library들을 직접 이용하여 모든 것을
다시 설계하는 것보다 훨씬 수월할 것이다. 신용카드 결재 방법을 바꾸었다고 하자. 그러면 단지 신용카드 결재 System, 그
중에서도 특정한 Class들만을 고치면되므로 수정도 용이하게 할 수 있다.
3.3.4 Rapid Prototyping
Prototype이란 한마디로 '시험판(Trial Version)'이라고 할 수 있다. 실제로 기업에서의 간부들은 '그들이 정말로 원하는 것이 무엇인지'를 제대로 알지 못하고 있는 경우가 대부분이다. 그들에게는 프로그램이 동작하는지 아닌지만 중요할 뿐이다.
3.3.5 System의 구축
Reusable Class들의 Library를 구축한다. 이 Class들을 이용하여 Working Model을 구축한다.
Rapid Prototyping을 이용하여 System을 구축한다. - 필요에 따라서는 이전의 단계로 되돌아갈 수 있다(Feedback).
3.4 Object-Oriented 방법의 장점과 단점
우선 짚고 넘어가야 할 점은, 기존의 사고 방식을 가지고 단순히 Object-Oriented Language를 사용하여
Programming을 하는 것은 별로 도움이 되지 않는다는 것이다. 이제까지 가지고 있던, Programming 할 때의
기존의 사고방식을 과감히 탈피하여 새로운 개념을 가지고 이에 적합한 분석과 설계가 뒤따라야만 Object-Oriented 방법의
장점을 충분히 살릴 수 있을 것이다.
- 설계 시간의 단축
기존에 만들어진 Module을 이용하여 Rapid Prototyping의 방법으로 소프트웨어를 구축하므로 시간을 절약할 수 있다.
- 질적인 향상
이미 충분히 검토되고 시험된 모듈을 이용하여 모아서 프로그램을 만들기 때문에, 필요에 따라서 그때그때 만든 것들 보다 더 높은
질을 가진 프로그램을 만들 수 있다. 이점은 Object-Oriented 방법으로 만들어진 Reusable Module을
사용하기 때문에 이루어지는 것이지 Object-Oriented 방법 자체가 질적 향상을 가능하게하는 것은 아니다.
- 유지 보수의 수월함
Object-Oriented 방법은 현실 세계를 그대로 소프트웨어 시스템으로 반영할 수 있으므로 결점을 발견하기가 쉽다. 또한
모듈화 되었으므로 결점을 고쳐도 그 파급효과가 다른 모듈에 끼치는 영향이 거의 없으므로 시스템을 유지하기가 수월하다.
- 제작 비용의 감소
기존에 만들어진 프로그램을 이용할 수 있으므로 프로그래밍의 노력이 줄어들고, Rapid Prototyping을 통해 시스템
디자인의 노력을 줄일 수 있고, 필요로 하는 모든 Class Library를 일일이 제작할 필요가 없이 시중에 나와있는 것들을
구입하므로, 회사의 경영 차원에서도 제작 비용을 줄일 수 있다.
- 대형 시스템구축의 수월함
Modular Programming과 Polymorphism도 대형 시스템의 구축을 가능하게 한다. Object-Oriented
방법으로만 가능한 그러한 것은 아니다. 일반적으로 대형시스템이라고 하는 것은 많은 추상화 단계를 거치기 마련이다. 그러므로
추상화를 지원하는 OOP가 좀 더 수월하게 대형시스템을 구축하도록 도와주리라는 걸 예상할 수 있으며, 실제로 그렇다.
- 더 나은 information 구조
현대의 기업사회에서 요구하는 복잡한 정보를 효과적으로 표현할 수가 있다. 이것은 Data Abstraction으로 가능하다.
- 적응성(adaptability)의 향상
수정을 가해도 그 영향이 국소화 되므로 필요한 부분만을 고쳐 쉽게 새로운 스템에 적용시킬 수 있다.
- Object-Oriented 방법의 미 성숙
어느 정도 기본적인 것은 갖추어 졌지만 Object-Oriented 방법은 아직 제대로 성숙되지 못했다. 이 방법을 믿고 사용하는데에 어려움이 따른다.
- 표준의 필요성
Programming Language에 대한 표준이 제대로 되어 있지 않기 때문에 프로그램을 이식하는데에 문제점이 있다. 이렇게
되면 소프트웨어를 같은 회사에서 구입해야 하고 다른 회사의 것은 섞어서 사용할 수 없게 된다. 이것은 큰 문제점을 야기할 수
있다. 만약 거래 회사가 망했다고 하자. 어떻게 할 것인가?
- 더 나은 도구(tool)의 필요성
Object-Oriented 방법을 바탕으로 시스템을 구축하는데 필요한 Tool 들은 몇가지가 있다. Object를 쉽게 설계할
수 있도록 해주는 것, Reusable Object들의 Library를 유지할 수 있도록 해주는 것, Data Input
Form과 출력을 셜계하고 유지할 수 있도록 해주는 것들이 있다. 새로운 방법론에 비해 그것을 지원해 줄 수 있는 Tool 들은
늦게서야 만들어지기 마련이지만, Object-Oriented 방법은 기존의 것과 상이하게 다르기 때문에 그들을 이용하기
힘들다는데 문제가 있다. 예를 들면, 현재 Class Library Management Tool 들은 기껏해야 간단한
Browser 정도만 제공할 뿐이다. 그들의 체계적인 분류, 사용 목적, 사용 방법 등에 관한 것은 충분히 지원하지 못하고 있다.
- 느린 개발 속도
객체지향은 처리하고자 하는 일에 대한 명확한 이해를 필요로 한다. 전체에 대한 잘못된 이해 혹은 분석이 부족한 상태에서 일을 시작하게 되면 프로그램 구조자체에 문제가 생길 수 있다. 초기설계에 많은 시간이 소모된다.
- 느린 실행 속도
Object-Oriented Language로 만든 소프트웨어들은 대체적으로 실행속도가 느리다. 추상화에는 많은 컴퓨팅파워가
소모된다. 기능이 강력하고 많은 만큼 속도가 상대적으로 느린 것은 당연하다 할 것이다. 하지만 Object-Oriented 방법
자체가 실행 속도를 중심으로 설계된 것은 아니기 때문에 속도는 큰 문제가 아닐 수도 있다.
- Conversion에 사용되는 비용
기존의 방법론을 Object-Oriented 방법으로 바꾸는 간단한 문제가 아니다. 새로운 Programming Language, DBMS
뿐만 아니라 그에 해당하는 여러가지 Tool 들, Graphics가 지원되는 Hardware System 들이 OOP를 필요로
한다. 그러므로 기존의 패러다임을 OOP로 바꾸는 작업이 필요하게 되는데, Conversion에 소요되는 비용을 간과할 수는
없다. 또한 물리적인 비용 뿐만이 아니라, Programmer와 설계자, Manager에게 들어가는 교육비용또한 상당하다.
3.4.3 장단점의 적절한 조화
- 성숙성
Smalltalk이나 C++, 그외의 기존 Programming Language에도 Object-Oriented 방법이 추가되어
새롭게 등장하는 프로그래밍 언어들은 OOPL을 사용하는 데에는 큰 불편함이 없다. 또한 이 새로운 개념을 전문적으로 취급하는
연구단체나 기업이 점점 늘어나고 있으며 이러한 연구단체나 기업들의노력으로 단점을 충분히 파악할 수 있게 되었다.
기존의 방법론과 비교해 보고 싶으면 동일한 Application을 기존의 방법을 이용하는 또다른 Team에게 맡겨보면 된다.
아마도 세가지 정도의 Application을 완성할 때 쯤 되면 Object-Oriented 방법의 장단점을 명확하게 파악할 수
있을 것이다. 이때 주의할 점은, Team 구성원 누구에게도 자신들이 시험의 대상이 되고 있다는 것을 알게해서는 안된다는
것이다. Heroic Effect(자신들이 시험의 대상이 되고 있다는 사실이 평소보다 더 열심히 한다든가 하는 등의 영향요소로
작용제로 Application을 개발할 때보다 수정하는 경우에 비용이 더 많이 소요되는 경우)가 종종 있기 때문이다.
객체지향은 패러다임의 변화를 요구하게 된다. 이 패러다임의 이해도에 따라서 개발자간에 커뮤니케이션 하는데 어려움이 생길 수
있다. 이차이는 개발자의 코딩능력과는 별개다. 십수년의 경력을 가지고 있다고 하더라도 객체지향적으로 프로그램을 만들어오지
않았다면 커뮤니케이션에 어려움이 생길 수 있다. 이러한 개발자간 커뮤니케이션의 문제점은 패턴에 대한 학습을 선행함으로써 상당부분 해결 가능하다.
:::

1 Linux More Popular as Deployment Platform
많은 개발자들이 자신의 실력을 다른 개발자들에게 자랑하기 위해서 혹은 그들과 의견을 주고 받기 위한 목적으로 오픈소스 프로젝트를 수행한다. 많은 경우 프로젝트 리더들은 프로젝트를 함께 개발하는 개발자의 소프트웨어 개발 환경에 대한 정보를 알기를 원한다.
이클립스 프로젝트는 4월 일반적인 개발자들이 어떠한 환경에서 개발을 하는지에 대한 광범위한 조사를 실시 했다. 주목할만한 내용은 개발플렛폼으로 리눅스가 상당한 진보를 이루어냈으며, 특히 배포플랫폼으로써는 윈도우즈를 추월했다는 점이 될 것이다.
이클립스 제단의 마케팅 디렉터인 Ian skerrit 이클립스를 사용하는 개발자의 64%가 윈도우즈를 사용하고 27%가 리눅스를
사용하고 있다는 결과를 발표하였다. 참고로 2007년 조사결과에 따르면 윈도우즈 사용자는 74% 리눅스 사용자는 20% 였다.
상당한 개발자가 리눅스를 개발환경으로 이동되었음을 알 수 있다.
deployment 플랫폼으로 보자면 리눅스가 43%로 41%의 윈도우를 앞지르고 있다.
개발자 커뮤니티는 데스크탑 개발환경과 deployment 개발환경을 지속적으로 리눅스로 바꾸어나가기 때문인 것으로 보고 있다. Skerrit는 그의 블로그에서 우분투와 레드햇으로의 이동은 분명한 이득을 주지만 윈도우즈는 그러하지 못하기 때문이라고 그 이유를 설명한다.
이러한 결과가 발생한 또 다른 이유는 리눅스 친화적인 Mysql과 Oracle과 같은 데이터베이스의 점유율 때문이다. 이들 두 데이터베이스의 점유율은 55%가 넘고 있다.
또한 이번 조사 결과는 기업들이 단지 오픈소스를 사용하기만 하는데에 머무르지 않고, 오픈소스에 공헌을 하는 정도로 오픈소스에 대한 인식이 성숙되었음을 보여주고 있다.
2007년에 46%의 기업들이 OSS의 사용을 허락했지만 OSS에 대한 공헌은 이루어지지 않았다. 즉 내부적으로 OSS를
사용하기만 했다. 지금은 이 비율이 27%로 줄었다. 이제 48.2% 의 응답자들이 그들의 기업이 OSS 커뮤니티로의 지원을
허락하고 있다고 응답을 하고 있다. 2007년의 37%에 비하면 10%나 증가한 수치다. - 국내의 경우에도 대략 2007년과
2008년을 기점으로 기업들의 오픈소스에 대한 직접적인 참여와 지원이 늘어나고 있다. -. OSS를 통한 비지니스 모델에 기대를
걸고 있다는 응답도 2007년 10%인 것에서 2008년 15.6%로 대폭 증가했다.
2 The Open Source Developer Report 2009
이 문서는 2009년 Eclipse Community 의 보고서인 The Open Source Developer Report를 보고 정리했다.
이 보고서는 다음과 같은 핵심내용을 포함하고 있다.
- 리눅스는 데스크탑과 서버 환경모드를 공유하고 있다. 개발자들이 개발을 위한 데스크탑운영체제로 Microsoft 윈도우즈에서 리눅스와 Mac OX로의 이동하는 모습이 분명히 감지되고 있다. 특히 depolyment 운영체제환경으로 리눅스는 가장 일반적인 플렛폼이 되었다.
- Mysql 과 Oracle 데이터베이스는 55%이상의 지배적인 점유율을 보여주고 있다.
- 형상관리도구로는 SVN(Subversion)이 57% 점유율을 보여주고 있다.
- 기업은 성숙한 OSS 모델을 받아들이고 있다.
- 더 많은 기업들이 오픈소스 소프트웨어의 사용과 기여에 참여하고 있다. 보고서에 따르면 2008년 48.2%였다. 2007년에는 37%였다.
- 15.6 %의 회사가 OSS에 연계한 비지니스 모델을 만들고 있다.
3 보고서 참여자 통계 자료
응답자의 반이상이 프로그래머였으며 기타 시스템 아키텍쳐, 매니저, 소프트웨어 품질관리 및 테스터, 마케팅 메니저 등이 참여하였다.
4 개발자 데스크탑 개발 환경
개발자가 사용하는 데스크탑 운영체제 통계정보를 보여주고 있다. 윈도우즈에서 Linux와 Mac OSX로 이동하는 것을 확인할 수 있다. 26.9%의 개발자가 주요 개발 데스크탑 환경으로 리눅스를 사용하고 있다고 응답했는데, 2007년에 비하면 7%가 증가한 수치다.
2007년에 비하면 10%가량 줄어들긴 했지만, 여전히 윈도우즈는 64%의 사용율을 가지는 지배적인 운영체제다. 가장 많이 사용되는 리눅스 배포판은 Unbuntu인 것으로 조사되었다. Mac OSX도 2007년 3.5%에서 6.9%로 증가했다.
- Windows Server or Client : 64.3%
- Linux : 26.9%
- Ubuntu 14.5%
- Fedora 3.4%
- SUSE 3.2%
- Debian 2.6%
- RHEL 1.3%
- 기타 배포판 1.8%
- Mac OSX : 6.9%
- Sun Solaris or OpenSolaris : 0.9%
- Other : 0.8%
4.1 IDE : 통합개발 환경
Eclipse IDE가 가장 인기있는 개발환경으로 지목되었다.
- Eclipse JDT : 60%
- Eclipse PHP 개발 툴 : 12.6%
- Eclipse C/C++ 개발 툴 - CDT - : 6.3%
4.2 형상관리 툴
SCM(Source code management), CMS(changes management) 그리고 BM(Build management)에 대한 사용율을 조사한 자료다.
SCM : 가장 널리 사용되는 소스코드 관리 시스템은 Subversion으로 57.7%의 사용율을 보였다. 20%의 CVS가
그 뒤를 따랐다. SCM으로는 오픈소스가 절대적인 위치를 차지하고 있음이 확인되고 있다. 단 5,000 명이상의 고용인을 가진
대기업의 경우에는 Subversion의 점유율이 41.3 %로 상대적으로 적었다는 점이 특이할만 하다. 최근 몇 년사이에
Subversion의 사용이 증가했는데, 일반적으로 대기업은 이러한 변화에 느리게 반응하는게 이유인 것 같다.
CMS : JIRA와 Bugzilla가 각각 17% 점유율을 기록했다. CMS는 아예 사용하지 않는다는 응답도 22.7%에 달했다. 예상과 달리 TRAC은 7.2%의 낮은 점유율을 보여주었다. Custom 즉 직접만들어서 사용한다는 응답이 8.4%에 달했는데, 이는 회사의 다른 정보들과 연동되어서 사용되어야 하는 CMS의 특성때문으로 생각된다.
BE : 33.4%의 Ant가 가장 널리 사용되는 것으로 확인되었다. CMS와 마찬가지로 21.7%의 비교적 많은 응답자가 BE를 사용하지 않는다고 응답을 했다.
5 언어 및 응용프로그램
자바는 커뮤니티에 의해서 주도적으로 사용되는 언어였으며, 76.6%가 그들의 첫번째 언어로 자바를 사용한다고 응답했다. 개발용도는 Server-Centric 30.2%, 웹이 24.7%, 데스크탑 애플리케이션이 23.4%였다.
이 보고서는 주요 3가지 개발용도에 대해서 각각 어떠한 툴 혹은 언어를 사용하는지에 대해서 조사했다.
5.1 Server-Centric 애플리케이션
server-centric 애플리케이션의 개발을 위해서 가장 널리 사용되는 되는 것은 servlet이였다. 그다음으로는 spring 프레임워크였으며, EJB도 38.3%로 널리 사용되는 것으로 조사되었다. 대표적인 server-centric 애플리케이션은 J2EE 애플리케이션, 데이터베이스 애플리케이션, ERP, CRM 등이 있다.
5.2 Web, Rich 인터넷 애플리케이션
웹과 rich Internet 애플리케이션 (RIAs)의 경우에는 주도적인 프레임워크나 툴이 없는 것으로 조사되었다. 오픈소스 Ajax 프레임워크, Flash/Flex 등이 많이 사용되었으며, 아예 사용하지 않는 다는 응답도 꽤 되었다. GWT가 많이 사용되고 있다는 점이 눈에 띈다.
5.3 Rich Desktop Applications
Eclipse RCP (47.6%)와 Swing (43.8%)로 양분되어 있는 모습을 보여주고 있다.
6 Deployment 환경
개발자들이 그들이 개발한 애플리케이션이 설치될 타겟 환경으로 어떠한 것을 이용하는지에 대한 조사내용을 포함하고 있다. 운영체제, 데이터베이스 그리고 애플리케이션 서버 환경에 대해서 조사를 했다.
리눅스는 주목할만한 Depolyment 타겟 운영체제로 성장을 했으며, 지금은 오히려 윈도우를 앞서고 있는 것으로 확인되었다.
2008년 기준 42.7%의 점유율을 보여주고 있는데 2007년의 37%에 비하면 5%가까이 증가한 수치다.
Ubuntu(12%), Red Hat Enterprise Linux (10.2%) 배포판이 널리 사용되고 있었다. 결과를 보면
윈도우환경의 유저가 리눅스, Mac OSX 등으로 이동한 것으로 보인다.
6.1 주요 데이터 베이스
예상대로 Mysql 과 Oracle이
각각 27.7%와 27.3%로 주요하게 사용되고 있었다. Mysql과 Oracle은 선호대상이 갈리는 것이 확인 되었다.
기업규모로 보자면, 5000 명 이상을 고용하고 있는 거대 기업의 경우에는 Oracle이 33.5%, IBM DB2가
10.7%, Mysql 이 11.6% 였다.
Oracle은 다음과 같은 선호대상층을 가진다.
- Java를 주요 개발언어로 사용하는 경우
- server-centric 애플리케이션을 개발하는 경우
- Application 서버를 이용하는 경우
Mysql은 다음과 같은 선호대상층을 가진다.
- PHP 언어를 주요언어로 사용하는 개발자
- RIA/Web 애플리케이션
6.2 주요 Application 서버
Apache Tomcat이 가장 널리 사용되고 있다. 그다음으로 JBoss, IBM WebSphere가 사용되고 있다. 아무
것도 사용하지 않는다는 응답도 25.3%나 되었다. 5000명이상 고용인을 가진 대기업의 경우에도 여전히 Apache
Tomcat이 가장 널리 사용되었으나 IBM WebSphere가 6.9%에서 12.0%로 크게 오르고 Apache Tomcat
는 34.8%에서 26%로 떨어진걸 확인할 수 있었다.
7 평가
몇년전만 하더라도 오픈소스는 기업에서는 받아들이기 힘든 모델이라고 평가되기도 했었다. 혹은 많은 기업들이 단지 오픈소스의 단물만 빨아먹으려고 할뿐 결코 오픈소스 모델에 참여하지는 않을 것이라고 생각되던 때도 있었다.
그러나 이 보고서에 따르면, 오픈소스는 메이저한 개발/배포 환경은 물론이고 비지니스 환경까지 그 영역을 지속적으로 확장시켜가고
있음을 확인할 수 있다. 더불어 분명하게 더 많은 기업들이 적극적으로 오픈소스 모델에 직접적으로 참여하고 있는 것도 확인할 수
있다.
대세는 OSS
 :::

저작권의 출현
쓰여진 글에 대한 저작권이 언제 출현했을까? 거기에 대해서 왠지 알아보고 싶어졌다. 당연히 쓰여진 글의 저작권이니까. 글이
종이든지 어디에든지간에 씌여진 시점부터라고 생각할 수도 있겠지만, 실제 저작권은 쓰기가 발명되고 난 뒤에도 한참이나 지나서
만들어졌다. 정확히 말하자면 쓰기가 내면화 되는 시점 - 대게는 인쇄가 일반화된 시점부터 본격적인 내면화가 시작되었다고 보고
있다 - 부터 만들어졌다고 봐야 될 것이다.
쓰기가 내면화 되었는지가 왜 중요한지에 대해서 알아봐야 겠는데, 그럴려면 최초 등장한 쓰기와 쓰기가 내면화된 시점의 쓰기의 차이점에 대해서 먼저 이해를 해야 될것 같다.
쓰기가 내면화되지 않은 시절에 말은 기억을 용이하도록 하기 위해서 예전부터 내려온 틀에박힌 정형구과 운율등을 이용했다. 영웅의 일대기를 그린 호머의 서사시가 대표적인 예가 될 것이다.
아킬레스가 분전을 했다. 라고 말하는 것보다 빠른발의 아킬레스는 영웅의 방패와 창을 들고 적진으로 돌진했다라는 식으로 표현하는게 훨씬 기억하기가 쉽기 때문이다. 오디세우스를 지모가 뛰어난 오디세우스라고 한다든지, 신과 같은 아가멤논이여라고 하는 것도 비슷한 이유에서다. 이러한 정형구적인 표현은 중세 작품에도 자주 등장한다. 잠자는 동안의 달콤한 꿈을 믿을 수 있다면 내 꿈은 필시 좋은 소식이 온다는 증거일 것이다.
- 로미오와 줄리엣 중-. 정형구적인 표현은 사람의 감성을 강하게 자극하기 때문에 적절히 사용한다면 매우 숭고하게 보이기도
한다. 그래서 호머의 서사시가 그동안 그렇게 높은 평가를 받아왔는지도 모르는 일이다. 지금은 이러한 표현은 거의 사용하지 않지만
말이다. 환타지 소설에서나 간혹 볼 수 있을 뿐이고, 가능하면 정형구적인 표현을 사용하지 말도록 지도를 받는다.
아뭏든.. 이들 정형구와 운율은 개인의 것이 아닌 집단에 의해서 전승된 공중의 지혜와 같은 것이기 때문에, 이들로 이루어진 결과물 역시 개인의 것이 아닌 집단의 것이라는 인식이 강했다. 그러니 저작권을 주장한다는 것 자체가 있을 수 없는 일이었다.
쓰기가 출현한뒤에도 오랫동안 저작권이라는 개념이 모호했는데, 왜냐하면 초기 쓰기는 지금의 쓰기와는 달리 사람이 말로
한것을 옮겨적는 작업이였기 때문이다. 공동의 재산이라고 생각되는 말을 종이에 고정시키는 작업이였다. 이당시 말로 된 작품이란
것은 과거의 지혜를 기억하기 좋게 운율이 가미되어서 전승된 정형구의 집합이였으니, 이들 과거의 지혜와 정형구들 운율들에 소유권을
주장할 수 없는 것이었다. 그것은 공동의 재산이였기 때문이다. 이경우 중요한 것은 저작권이 아니라 그 지혜를 말로써 나타낼 수
있는 능력을 가진자 즉 시인 혹은 나이를 먹은 지혜로운 노인들이였다.
노인이 천대받는다고 걱정들이 이만저만이 아니다. 슬프다고 생각할지 모르겠지만 이것은 당연한 현상이다. 지금 지혜는 구전되는
말로써 전달되는게 아니다. 시간과 공간에 독립된 문자에 의해서 전달되고 공유되어진다. 현대사회에서 노인의 지혜는 거의 쓸모가
없어졌다. 물론 노인이 가지고 있는 삶의 지혜는 중요한 자산이 될 수 있겠으나 자본주의 사회에서 돈으로 환산되지 않는 삶의
지혜는 쓸모가 없어진다. 대게는 할일 없는 노인의 쓸데없는 잔소리 취급받는다. 그러니 노인이 버려질 수 밖에.. 이건 덤으로
드는 생각인데, 노인이 되어서 버려지지 않기 위해서는 자기 스스로의 생산수단을 가지는 수 밖에 없다. 농사든지 뭐든지간에
말이다. 그렇지 않다면, 당신이 왠만큼의 돈과 지식과 정보를 가지지 않는 한은 폐기처분 될 걸 각오해야 할 것이다.
본론으로 되돌아와서 인쇄술이 발달해서 본격적인 쓰기가 정착되면서, 동시에 프라이버시 의식 역시 성숙하게 된다. 기존의 말하기가
집단과의 교류하는 행위라면 쓰기와 읽기는 개인의 내면과의 대화이기 때문이다. 혼자 짱박혀서 무엇인가를 할 수 있는 개인만의 공간이
라는 것이 이때부터 생겨나고 여기에서 프라이버시라는게 자라난다. 물론 그전에도 몇몇 작가들이 그러한 개인적인 행위를 해오긴
했지만 극히 예외적인 경우였다. 또한 창작의 행위가 가능했는데, 글로 적혀지면 기억할 필요가 없기 때문에 고리타분한 정형구적
표현을 벗어던지고 자신만의 생각을 글로 옮길 수 있게 되었기 때문이다.
이렇게 해서 씌여진 문서나 책은 공중과 집단의 것이 아닌, 개인이 창작해서 만들어낸 소유할 수 있는 물건의 성격을 띄게 된다. 이러한 과정을 거쳐서 자신의 물건에 대해서 소유권을 주장하듯이 자신이 만들어낸 글에 대해서 소유권을 주장하는 저작권의 개념이 만들어지게 된다.
이후에 글과 문서에 대한 저작권의 개념이 확고해지고 최근까지 안정적으로 유지된다. 이것은 인터넷시대에까지 계속 유지되게 된다.
왜 아시아는 저작권이 잘 지켜지지 않는가 ?
인터넷 컨텐츠에 대한 저작권이 특히 아시아지역에서 잘 지켜지지 않는 것에 대해서, 그들이 교육을 못받아서, 미개해서, 심지어
양심이 버려서라는 평가를 하기도 한다. 하지만 조금만더 돌이켜 생각해보면, 이것은 문화적차이 때문인거지 교육을 받지 못했거나
미개하기 때문인 것은 아니라는 걸 알 수 있다.
서양은 이른 시간에 쓰기를 내면화 시켰고 이에 기반해서 개인주의를 발전시켰다. 반면 동양은 여전히 개인적이라기 보다는 좀더
집단친화적이고 공동체의 가치를 중요시 하는 경향이 있다. 이러한 공동체의 가치를 중요시 하는 문화 즉 구술적문화에서는 컨텐츠를
개인의 것이 아닌 집단의 것으로 생각하는 경향이 강하게 남아 있다. 과거 쓰기가 내면화 되기 전의 사람들이 그랬던 것 처럼
말이다. 그래서 이들은 여전히 컨텐츠가 순전히 개인의 물건이라는 개념을 쉽게 받아들이지 못하는 것이다.
동양인들의 인식이 저급하기 때문이 아니라는 것이다. 물론 많은 사람들이 진보라는 것을
개인주의에 기반한 자본주의가 얼마나 제대로 뿌리를 내렸는가로 판단하려고 하기 때문에, 동양의 그러한 공동체적 마인드 자체를
저급하게 생각하는 경향이 있긴 하다. 그러나 동양적인 마인드와 서양적인 마인드는 서로 다른것이지
등급을 메길 수 있는 그런건 아니다. 유럽을 중심으로 하는 공동체생활방식의 등장, 자본주의에 대한 위기론 혹은 회의론들,
동양철학에 대한 재평가, 뿔뿌리 공동체라고 할 수 있는 오픈소스운동과 자유소프트웨어 운동 등에서 나타나듯이 말이다.
자유소프트웨어와 저작권
자유소프트웨어 공동체와와 오픈소스 공동체는 자본주의와 개인주의에 기반한 생각과 지혜의 물건화와 사유화에 반대한다. 이들은 생각, 아이디어는 함께 공유해야할 공동의 자산이라고 본다. 고대의 서사시처럼 말이다.
어떻게 보면, 자유소프트웨어와 오픈소스는
서양보다는 동양에 어울리는 운동이라고 볼 수 있다. 이러한 운동이 오히려 서양에서 먼저 시작되고 서양에서 뿌리를 내리고 있는
것은 모순이라고 볼 수 있을 것이다. 자본주의가 먼저 뿌리를 내렸고, 공동체정신이 거의 남아있지 않았기 때문에 오히려 그에 대한
반성으로 먼저 서양사회에서 생겨난게 아닐까 ?
이러한 반저작권 혹은 반자본주의적 운동이 소프트웨어영역에 쉽게 뿌리내린 이유는 인터넷이란 매체의 특징이 한 몫 한것으로 생각된다. internet은
애초에 관리주체나 중심이 없는 상태로 설계되었는데, 이는 자원과 노동력을 집중시키는 자본주의와는 많은 차이를 보인다. 예컨데
인터넷은 독점적인 권한을 가지는 개인 혹은 집단이 관리하는 사유재산이 아닌 인류공동의 재산이라는 인식이 초기에 생성이 되었다.
이러한 인식하에서 자유소프트웨어 재단이 있게한 해커문화가 생겨나게 되었고, 인터넷의 자본화에
맞서서 강력한 풀뿌리 공동체를 지켜내는 원동력이 되었다. 그 어떤 산업분야에서도 볼 수 없는 (독점적인 저작권에 기반하지
않은)자유로운 정보공유, 서로 연대하며 서로를 존중해주는 공동체 문화를 간직하고 있다. :::

지각문화
다른 산업분야와는 달리 소프트웨어 업계는 지각문화가
안정적?으로 자리를 잡은 거 같다. 더불어 야근문화까지 안정적으로 자리잡았다는게 꺼림찍하긴 하지만 말이다. 이쪽 바닥에 계속
일했던 사람들이라면 뭐 9시반에서 10시사이에 출근을 하거나 혹은 10시가 넘어서 출근해도 뭐 그닥 느낌이 없을 수도 있을 것
같다. 내 출근 시간이 대략 9시반에서 10시 사이인데, 이제 막 출근해서 엘리베이터를 타려는 사람들로 북새통을 이룬다.
대충 청바지에 대략적인 흰면티, 가끔 슬리퍼에 간혹반바지와 더해서 아주 일상적으로 경험할 수 있다.
때때로 대신 10시까지 출근했다면 7시까지 일을 하게되니, 어차피 일하는 시간은 비스무레하다라고 주장할 수 있을 것 같지만
주위에서 주워들은바 다른 산업분야에서는 이해가 되지 않는 문화들이시다. 내 친구의 형은 8시반에 출근한다. 그렇다고 해서
5시반에 퇴근하느냐 하면 퇴근 시간은 7시다. 10시에 출근하고 대신 7시에 퇴근한다? 요런건 생각조차할 수 없는 곳들이
태반이다.
이러한 와중에 유독 소프트웨어 업계에 지각문화가 안정적으로 자리 잡은 이유에 대해 생각을 해보았다. 좀 뜬금없지만 말이다.
시간엄수 문화
시간은 금이 되었고 시간을 제대로 지키지 못하는 사람은 상종치 못할 사람이 되었다. 그러다 보니 좀 바쁘게 사는 사람은 좀
과장하자면 분단위로 시간을 관리를 해야 한다. 시간을 제대로 지키는 것은 의무이자 인간의 본성처럼 인식되는게 지금이다.
하지만 시간엄수문화는 그 역사가 그리 오래되지 못했다. 산업화시대를 거치면서 우여곡절
끝에 정착이되었으며, 고작해야 한 100년정도가 되었을 뿐이다. 비교적 산업화에 늦게 진입했던 우리나라의 경우 시간엄수문화가
정착한건 50년이 채 안된다. 지금은 잊혀진 얘기지만 코리안타임 이라고 해서, 약속시간에 30분정도 늦는것은 애교로 봐주던 때가
그리 오래전이 아니다.
그렇지 않은 대부분의 시간 즉 최근의 100년정도를 제외한 나머지 수십만년의 기간동안 인류는 시간을
인식하면서 살지 않았다. 아니 그렇게 살아갈 필요가 없었다. 자연은 분단위로 시간을 맞출 것을 인간에게 요구하지 않았기
때문이다. 게다가 시간의 표준은 어떻게 할 것인가 ? 그리스도가 태어난날로 ? 아니면 그리스도가 못박힌날 ? 석가모니가 태어난날
? 공자생일 ? 왕이 바뀐날 ?? 대략 보름단위로 씨뿌리는 날 수확하는날, 비가올것 같은 날 정도를 예상할 수만 있으면 되었다.
시간엄수는 인간의 본성이 아니다. 인류가 살아왔던 전체시간 중에 고작 0.x% 정도인 최근에서야 시간개념이라는 것이 생겨났다. 사람은 천성적으로 (지금보다는 훨씬더) 게으른 존재다. 산업화를 거치면서 산업과 자본의 요구에 따라서 지금처럼 과도하게 부지런해지도록 길들여진 것이다. 천성을 거슬려고 하다보니 자기자신과 싸워야 하는게 아니겠는가 ?? 서점에 가보면 게으름을 다른 시각으로 바라보는 책이 늘어난 것을 볼 수 있는 것도 이러한 이유 때문아닐까 싶다. 자고로 천성을 거스르면 행복과도 그만큼 멀어질 확률이 높다.
소프트웨어 분야에 종사하는 사람들은 다른 산업분야와는 달리 자유소프트웨어 공동체, 오픈소프트웨어 공동체, 해커 공동체 등의
자유로운 풀뿌리 공동체 덕분에 자본화, 다른말로 산업역군화 또다른 말로 기계화가 덜 진행된 것이리라 생각된다. 그러다 보니 시간엄수가 비교적 덜 내면화 되고, 시간감각이 무뎌디게 된게 아닐까 생각해 본다. 지맘대로 출퇴근을 해대는 개념없는? 개발자나 디자이너 얘기를 어렵잖게 듣는 이유일 것이다. :::

책 파괴의 세계사 ISBN : 8991482163 를 읽고
가장 많은 책을 파괴한 집단
은 역시 종교집단. 그 중에서도 유일신을 믿는 종교집단이다. 이 책을 읽다보면 수많은 책을 파괴한 종교의 야만적인 행위에, 분노게이지가 차곡차곡 쌓이는걸 느끼게 될 것이다. 책 부제도 책 파괴의 야만적인 역사 이다. 나 이외의 다른 신을 두지 말라라
는게 유일신교의 제일 교리이기도 하고 다른신을 상징하는 것은 물건이건 책이건 간에 모조리 불태워 없애라고 했으니 그럴수 밖에
없었을 것 이라고 이해해줘야 하는건가? 그 다음이 아마 전쟁과 독재자들 때문이였던 것으로 생각된다. 전쟁을 버린 이유의
상당부분이 종교문제 때문 이였을 테니 역시 책을 파괴한 제일 원흉?은 종교집단인게 분명해 보인다. 이외에
홍수,지진,화산폭발,좀벌레,습기 같은 것들이 있긴 했지만 예상외로 자연재해로 책이 파괴된 것은 약 30%정도에 불과한 것으로 이
책은 설명하고 있다.
유일신교, 독재자, 전쟁광의 공통점은 타인을 타인의 사상을 인정하지 않는다는 점일 것이다. 뭐 종교인이야 독재자와 전쟁광과는 목적이 다르다라고 주장할 수도 있을 것이다. 더 아름다운 세상을 만들기 위해서 !!.
신이 잘못된게 아니고 인간이 잘못된 것이다라고 할 수도 있겠으나, 종교집단이 책을 비롯한 수많은 문화유산을 파괴한건 사실이니
때로는 비난을 피해가기 힘들 것이다. 지금은 뜸하지만 멀쩡한 20세기 민주국가라고 하는 대한민국에서도 그러한 일이 벌어졌기도
했고 말이다.
하긴 유일신 야훼는 바이러스와 야동이 설쳐대는 세상을 더이상 보지 못하여서 물로 깨끗하게 포맷까지 해버리지 않았는가.
책에 적혀 있었다
책을 파괴하고자 하는 이유는 책에 그러하게 적혀있었다라고 하면 진실처
럼 생각을 하기 때문이다. 사실과 진실은 다르다. 책에 사실이 적혀있었다고 하더라도 그것이 진실인 것은 아니다. 신자유주의를
도입한 이래 성공적으로 성장을 한 국가의 예를 들어서 신자유주의를 옹호하는 책이 있다고 생각해 보자. 이것은 사실이다. 그러나
반대로 신자유주의가 도입된 이후 오히려 삶의 질이 현저히 떨어진 국가와 계급을 예로 들면서 신자유주의에 반대하는 책이 있다.
이것도 사실이다. 그럼 뭐가 진실인가 ?
그 판단은 책을 읽는 사람의 몫이다. 그러나 독재자는 여러가지 사실이 존재하는걸 싫어 한다. 자신이 제시하는 하나의 사실만이
존재하길 한다. 사실이 하나라면 그게 곧 진리가 되지 않겠는가 ? 자유민주주의사회는 여러가지 사실이 존재한다는 것을 인정한다.
이런 이유로 모든 독재자가 반민주적인 것은 필연적일 수 밖에 없는 것이다. 그러니 무뉘만 민주주의 대한민국에서 나쁜 사마리아인과
같은 책이 국방부 지정 금서목록씩이나 되는 것이다. 헤게모니를 쥐고 있는 자본가들에게 또다른 사실을 말해주는 그러한 책이 여엉
불편한 것이다. 뭐 불편할 수도 있다. 불편한 사실이라는 것도 있으니까. 문제는 자신들의 힘을 이용해서 불편한 사실을 통제하고
마음편한 사실만 유통되도록 통제하려고 하는데에 있다.
그래서 그들은 책을 불태우고 금서목록을 만들고 인터넷에 대한 통제를 시도한다. 정보통제, 정보파괴는 고금을 통틀어 독재자의
공통분모다. 물론 걔들은 얘기한다. 세상이 시끄러워진다고. 지금의 이 정부도 그러한 생각으로 정보를 통제하고, 금서목록을 생산해
내시고 계신다.
인터넷 시대의 정보파괴 행위
과거에는 정보를 차단하고 파괴시키는게 비교적 쉬웠을 것이다. 책은 소수의 필사자에 의해서 엄청난 공을 들여서 오랜시간에 걸쳐
만들어 졌다. 복사라는 개념자체가 없었으니 복사본이 돌아다니는 것도 아니다. 사상가 몇명 잡아서 족치고, 여기 저기 돌아다니는
몇개 안되는 책 불태우고 필사자들 몇명 관리하면 그걸로 끝이었다.
매체 기술은 흔히 대량의 복사, 빠른 전달이 가능한 방향으로 발전을 하는 것 같다.
대부분의 정보가 인터넷에서 실시간으로 그리고 무한대로 복사되는 지금에 와서 정보를 통제한다는 것은 기술적으로 거의 불가능 하게
되었다. 고작해야 조금 귀찮게 하는 정도라고나 할까 그 정도다. 그래도 2MB 정권은 통제를 하려고 하신다. 이러니 youtube 실명확인 거부와 같은 헤프닝이 북한도 아니고 중국도 아닌 대한민국에서 벌건 대낮에 벌어지고 있다.
전자책이 책파괴의 역사를 근절시켜 줄 것인가 ?
다시 책파괴 얘기로 되돌아와서 그렇다면 전자책이 책파괴의 역사를 근절시켜줄 수 있을까 ? 독재스러운 얘들 혹은 광신스러운 얘들에게서 책을 지켜줄 수 있을까 ?
전자책이 그러한 과업을 수행하기엔 힘이 부칠 것이라는 예상을 하는 사람들도 있다. 여기에는 몇 가지 이유가 있다. 최신
기술이라고 하는 것들이 종이책에 비해서 그다지 내구도가 높지 않다는게 아마 가장 큰 이유일 것이다. 최신 저장매체가 종이보다
내구도가 높지 않다는 것은 사실인 것 같다. 종이책의 경우 습기, 좀벌레와 같은 적들이 내구도를 깍아 먹는다고 하더라도 전쟁과
같은 적대적인 파괴행위가 없다면 수백년은 어렵지 않게 보관이 가능하다. 여기에 좀더 관심을 가진다면 천년이 넘는 시간도 버텨낼
수 있을 것이다. 집에 뒹굴어 다니는 책들의 경우에도 책장에만 잘 꽂아주는 정도로 수십년 혹은 백년이상 좋은 상태로 보관이 가능
하리라 생각된다.
CD 혹은 DVD에 정보를 저장하면 반 영구적으로 보관할 수 있을 것이라고 선전한다. 지금에 와서야 이 거짓말을 믿는 사람은 없을 것이다. 종이보다도 훨씬 내구도가 떨어지는게 디지털 저장매체들이다.
그렇지만 이들 디지털 매체는 쉽게 복사 가능하다는 특징으로 물리적 내구도를 크게 향상시킬 수 있다는 점이 간과되어서는 안될 것이다. 디지털 정보는 아날로그 정보에 비해서 보기가 불편하다는 문제도 조금씩 해결 되고 있다.
cool ebook from seppelpeppel on Vimeo.
책의 저자는 디지털로 된 책이 저장되는 천국의 도서관을 상상한다. 책을 읽고자 하는
사람은 언제든지 쉽게 다운로드 받아서 자신의 단말기를 통해 읽어 볼 수 있다. 이 천국의 도서관은 게다가 여러곳에 분산되어서
위치할 수 있으므로, 지구적인 재앙이 일어나기 전에는 완전히 사라지지 않을 것이다. 네트워크 환경이 충분히 갖추어져 있다면, 위키피디아에서 처럼 손실된 정보를 사람들이 다시 복구할 수도 있을 것이다.
지금 구글과 아마존이 그러한 작업을 하고 있다.
내 생각에 가까운 미래의 도전할만한 인터넷 서비스는 전자책분야일 것 같다. 요즘 이쪽에 부쩍 관심이 간다.
관련글
:::

아오.. 일단 포스팅 하고 보자..
 문서는 완성된게 아니며, 틀린 내용이 있을 수 있습니다. 수정해야 할 부분이 있음 알려주세요. 확인 후 반영하도록 하겠습니다.
1 Thread에 대해서
프로그램을 병렬로 실행시키는 방법으로 fork()에 대해서 알아보았다. fork()는 매우 이해하기 쉬운 프로그래밍 방법이긴 하지만 자원효율성에서 몇가지 문제점을 가지고 있다. 프로세스는 기본적으로 code, data, stack, file I/O, 그리고 signal table의 5가지 요소로 구성이 된다. fork()
를 이용해서 새로운 프로세스를 생성하게 되면, 이러한 5가지 구성요소가 모두 복사가 된다. 그러하다 보니 프로세스를 생성하는데
많은 비용이 소비될 것이다. 대게의 경우에는 프로세스를 새로 생성시킬때 발생하는 성능저하가 문제가 되지는 않겠지만 웹서비스처럼
대량의 접근이 발생하는 영역에서는 문제가 될 수 있다.
fork의 이러한 방식은 상당히 효율이 떨어지는 측면이 있다. 어떤 프로그램을 병렬로 실행시킨다고 했을 때, 실제 우리가 병렬로 실행되기를 원하는 영역은 코드의 일부분이지 프로그램 전체는 아니기 때문이다.
// ... pid = fork(); if (pid > 0) { // 실제는 이 부분의 코드만 병렬로 실행되면 된다. // fork()는 다른 모든영역의 코드가 복사되어 버린다. }
게다가 전혀다른 프로세스를 생성시킴으로써, 프로세스간 통신이라는 상당히 복잡한 문제까지를 해결해야 한다. 병렬로 작동하는
프로그램은 특성상 데이터를 공유하거나 서로 통신을 해야 하는 경우가 많다. 그런데 프로세스는 서로 독립된 객체이므로 일반적인
방법으로는 데이터를 공유할 수가 없다. 이러한 프로세스간 데이터 통신을 위해서 리눅스는 IPC라는 설비를 제공하는데, IPC라는게 사용하기가 여간 까다롭지가 않다. IPC에 대해서는 별도의 장을 할애해서 다룰 계획이다.
Thread를 이용하면 fork()를 이용한 프로세스 기반의 병렬처리의 문제점의 많은 부분을 해결할 수 있다. Thread는
새로운 프로세스를 생성시키지 않고, 특정 문맥(코드)만을 병렬로 실행할 수 있도록 허용한다. 새로운 프로세스를 생성시키지 않기
때문에 그만큼 자원을 아낄 수 있으며, 더 효율적으로 빠르게 움직일 수 있다. 또한 같은 프로세스이기 때문에, 데이터를
공유하기가 쉽다는 장점도 가진다.
1.1 Thread vs Process
Thread는 프로세스와 다음과 같은 차이점을 가진다.
- 프로세스는 독립적이다. 쓰레드는 프로세스의 서브셋이다.
- 프로세스는 각각 독립적인 자원을 가진다. 쓰레드는 stat, memory 기타 다른 자원들을 공유한다.
- 프로세스는 자신만의 주소영역을 가진다. 쓰레드는 주소영역을 공유한다.
- 프로세스는 IPC를 이용해서만 통신이 가능하다.
- 일반적으로 쓰레드의 문맥교환(context switching)는 프로세스의 문맥교환보다 빠르다.
1.2 Multi Thread 프로그램의 단점
모든 도구가 그러하듯이 Multi Thread 프로그램이라고 해서 장점만 가진 것은 아니다. Multi Thread 프로그램은 Multi Process 프로그래밍 방식에 비해서 다음과 같은 단점을 가진다.
- 하나의 쓰레드에서 발생된 문제가 전체 프로세스에 영향을 미친다.
멀티 프로세스의 경우에는 프로세스하나가 문제가 생기더라도 단일 프로세스로 문제가 제한된다. 그러나 멀티쓰레드 프로그램의 경우
하나의 쓰레드에 생긴 문제가 다른 쓰레드에까지 영향을 줄 수 있다. 예를 들어 쓰레드 하나가 다른 프로세스의 메모리 영역을
침범할 경우 프로세스 자체가 죽어버림으로써, 프로세스에 생성된 다른 모든 쓰레드도 프로세스와 함께 죽어버리게 된다. - 이
문제는 해결 가능하지만 여기에서는 다루지 않도록 하겠다. 시그널을 잘 활용하면 된다. 관심있으면 한번 고민해 보기 바란다. -
- 디버깅이 어렵다. 문맥이 서로 교환되므로 추적하기가 까다롭다.
이러한 단점이 있음에도 불구하고 멀티쓰레딩 프로그래밍 기법을 선호하고 있다.
1.3 PThread
Thread는 운영체제에서 제공하는 병렬처리 메커니즘으로, 실제 이 메커니즘을 이용하기 위해서는 Thread의 구현체가 필요하다.
리눅스에서는 pthread라는 thread 구현 라이브러리가 사용되고 있다. pthread는 POSIX thread 의 줄임말로 POSIX 표준을 따르고 있다. pthread는 리눅스 뿐만 아니라 다른 거의 대부분의 유닉스에서도 사용할 수 있다. 이외에도 BSD 계열에서 사용하는 ' Light Weight Kernel Threads , Apple 에서 사용하는 Multiprocessing Services등의 구현체가 있다. 이 문서는 pthread구현만을 설명하도록 할 것이다.
pthread는 리눅스 운영체제에서 제공하는 thread 를 제어하기 위한 함수들을 모아 놓은 C 라이브러리로, 다음과 같은 기능의 함수군을 제공한다.
1.4 Multi Thread 프로그램
병렬로 작동하지 않는 하나의 문맥흐름만을 가지는 프로그램을 단일 쓰레드 프로그램이라고 한다. 반대로 아래와 같이 문맥이 나뉘어서, 동시에 두개 이상의 쓰레드가 실행되면, 이를 멀티 쓰레드 프로그램'''이라고 한다.
1.5 Process, Kernel Thread, User Thread
프로세스는 가장 무거운 커널의 스케쥴링 단위이다. 프로세스는 운영체제에게 할당받은 자원들 - 파일 핸들러,소켓,장치 핸들러 - 을 할당받게 된다. 프로세스는 독립된 단위로써 파일이나 주소영역 등을 공유하지 않는다.
kernel thread는 가장 가벼운 커널 스케쥴링 단위다. 하나의 프로세스는 적어도 하나의
커널 쓰레드를 가지게 된다. 만약에 프로세스가 하나이상의 쓰레드를 가지고 있다면, 이들 쓰레드는 같은 메모리와 파일자원등을
공유하게 된다. 만약 커널의 프로세스 스케쥴러가 선점형이라면 쓰레드의 스케쥴러도 선점형인 경우가 많다. 참고삼아서 선점형과
비선점형에 대해서 간략하게 설명하도록 하겠다.
- 비선점형 : 특정 프로세스가 CPU를 독점하는 것이 가능하다.
- 선점형 : 특정 프로세스가 CPU를 독점하는게 불가능하다.
특정 프로세스가 CPU를 독점하는게 불가능하게 하는 것은 프로세스가 인터럽트를 무시하기 못하게 하는 것으로 구현한다. 선점형은
어떤 프로세스가 시스템콜을 수행중이더라도 커널이 인터럽트를 보내면, 즉시 빠져 나와야 한다. 즉 운영체제가 CPU를 선점한다는
얘기가 된다. 시스템콜이 수행중이더라도 인터럽트를 걸고 다른 일을 수행하도록 할 수 있으므로 보다 빠른 반응성을 보여준다.
때때로 쓰레드가 유저영역 라이브러리로 구현되는 경우가 있는데, 이를 user Thread 라고 부른다.
1.6 쓰레드의 생성과 종료
멀티 쓰레드 프로그램이라고 하더라도, 처음 시작되었을 때는 main()에서 시작되는 단일 쓰레드 상태로 작동이 된다. 이 상태에서 pthread_create(3) 함수를 호출함으로써, 새로운 쓰레드를 생성할 수 있다. pthread_create를 이용해서 생성된 새로운 쓰레드를 worker 쓰레드라고 하자.
멀티 쓰레드 프로그램은 다음과 같은 흐름을 가진다.
생성된 worker thread는 언젠가 종료가 될 것이다. Master Thread (이하 부모 쓰레드)는 pthread_join()을 이용해서 worker thread들의 종료를 기다린다. pthread_join()는 종료된 worker thread의 자원을 정리하는 일을 한다. fork()를 이용한 멀티 프로세스 프로그램에서, 부모 프로세스가 wait()를 이용해서 자식 프로세스를 기다리는 것과 같은 이유라고 보면 된다.
1.6.1 pthread_create : 쓰레드 생성
pthread_create(3)함수를 이용하면 새로운 쓰레드를 생성할 수 있다. 이 함수는 다음과 같이 사용할 수 있다.
#include <pthread.h> int pthread_create(pthread_t * thread, pthread_attr_t *attr, void * (*start_routine)(void *), void * arg);
- thread : 쓰레드가 성공적으로 생성되었을 때, 넘겨주는 쓰레드 식별 번호.
- attr : 쓰레드의 특성을 설정하기 위해서 사용한다. NULL일 경우 기본 특성
- start_routine : 쓰레드가 수행할 함수로 함수포인터를 넘겨준다.
- arg : 쓰레드 함수 start_routine를 실행시킬 때, 넘겨줄 인자
이 함수는 성공적으로 수행되었다면, 0을 리턴한다. 그렇지 않을 경우 1을 리턴한다.
1.6.2 pthread_join : 쓰레드 정리
쓰레드가 실행시키는 것은 함수 이다. 그러므로 return이나 exit(0)등을 이용해서 쓰레드를 종료시킬 수 있게 된다. 그러나 쓰레드 함수가 종료되었다고 해서 곧바로 쓰레드의 모든자원이 종료되지 않는다. fork()기반의 멀티프로세스 프로그램에서 종료된 자식프로세스를 정리하기 위해서 wait()로 기다리듯이, 종료된 쓰레드를 기다려서 정리를 해주어아만 한다. 그렇지 않을 경우 쓰레드의 자원이 되돌려지지 않아서 메모리 누수현상이 발생하게 된다.
pthread_create()로 생성시킨 쓰레드는 pthread_join()을 통해서 기다리면 된다. pthread_join 함수는 다음과 같이 사용할 수 있다.
#include <pthread.h> int pthread_join(pthread_t th, void **thread_return);
- th : pthread_create에 의해서 생성된, 식별번호 th를 가진 쓰레드를 기다리겠다는 얘기다.
- thread_return : 식별번호 th인 쓰레드의 종료시 리턴값이다.
pthread_join이 하는 일은 명확하다. 다만 주의 할것은 pthread_join은 반드시
joinable 한 상태로 생성된 쓰레드만을 기다릴 수 있다는 점이다. pthread_create로 쓰레드를 생성시킬 때,
나중에 join되지 않을 것으로 생각하고 생성시킬 수 있는데, 이렇게 되면 이 쓰레드는 종료하자마자 모든 자원을 해제하며,
pthread_join으로 기다릴 수가 없다. 부모쓰레드와 떨어져서 완전히 독립적으로 작용한다고 하여, 이를 detach 한다고 한다. 쓰레드를 detach하는 방법은 아래에서 다룰 것이다.
pthread_create와 pthread_join을 알고 있다면, 이제 thread를 생성시킬 수 있다.
#include <pthread.h> #include <stdio.h> #include <unistd.h> #include <stdlib.h> // 쓰레드 함수 void *t_function(void *data) { int id; int i = 0; id = *((int *)data); while(1) { printf("%d : %d\n", id, i); i++; sleep(1); } } int main() { pthread_t p_thread[2]; int thr_id; int status; int a = 1; int b = 2; // 쓰레드 생성 아규먼트로 1 을 넘긴다. thr_id = pthread_create(&p_thread[0], NULL, t_function, (void *)&a); if (thr_id < 0) { perror("thread create error : "); exit(0); } // 쓰레드 생성 아규먼트로 2 를 넘긴다. thr_id = pthread_create(&p_thread[1], NULL, t_function, (void *)&b); if (thr_id < 0) { perror("thread create error : "); exit(0); } // 쓰레드 종료를 기다린다. pthread_join(p_thread[0], (void **)&status); pthread_join(p_thread[1], (void **)&status); return 0; }
아주 전형적인 프로그램이긴 하지만 pthread_join부분에 문제가 있다. pthread_join은 쓰레드가 종료될 때까지 블럭되기 때문이다. 이래서는 쓰레드를 두개이상 생성시키지 못할 것이다. 그렇다고 pthread_join을 이용하지 않는다면, 메모리 누수가 생기게 되니, 생략할 수도 없는 노릇이다.
1.6.4 자식쓰레드를 부모쓰레드로 부터 분리하기
pthread_join의 사용으로 발생할 수 있는 문제점을 해결하기 위한, 가장 좋은 방법중의 하나는 pthread_detach
를 이용해서, 자식 쓰레드를 부모쓰레드와 완전히 분리해 버리는 방법이다. 이 경우 자식 쓰레드가 종료되면, 모든 자원이 즉시
반환된다. 반면, 자식 쓰레드의 종료상태를 알 수 없다는 문제가 발생한다. 대게의 경우 자식 쓰레드의 종료상태가 중요한 문제가
되지는 않을 것이다.
만약 자식 쓰레드의 종료상태를 알아내는게 중요하다면, 종료상태를 저장할 전역변수를 두고, 여기에 종료상태를 기록하는 방식을
사용할 수 있을 것이다. 자식 쓰레드가 종료할때, 변수의 값을 바꾸고, 부모쓰레드에 시그널을 전송하는 방법이다. 이 방법은 이
문서의 뒤에서 따로 다루도록 하겠다.
#include <pthread.h> #include <stdio.h> #include <unistd.h> #include <stdlib.h> // 쓰레드 함수 // 1초를 기다린후 아규먼트^2 을 리턴한다. void *t_function(void *data) { char a[100000]; int num = *((int *)data); printf("Thread Start\n"); sleep(5); printf("Thread end\n"); } int main() { pthread_t p_thread; int thr_id; int status; int a = 100; printf("Before Thread\n"); thr_id = pthread_create(&p_thread, NULL, t_function, (void *)&a); if (thr_id < 0) { perror("thread create error : "); exit(0); } // 식별번호 p_thread 를 가지는 쓰레드를 detach // 시켜준다. pthread_detach(p_thread); pause(); return 0; }
1.7 쓰레드 동기화
이제 우리는 간단한 다중쓰레드 프로그램을 만들 수 있게 되었다. 그러나 이들 쓰레드 생성 함수만 가지고는 복잡한 쓰레드 프로그램을 만들 수가 없다. 쓰레드간 동기화라고 하는 문제가 놓여있기 때문이다. 아주 간단한 프로그램이 아닌한은 반드시 동기화문제를 고민해야만한다.
동기화란 여러가지 의미로 사용될 수 있는데, 이 경우에 있어서 동기화는 서로의 시간을 맞춘다를
의미한다. 멀티쓰레드 프로그램은 하나의 시간에 여러개의 프로세스가 돌아가는 형태를 취한다. 또한 멀티쓰레드 프로그램은 자원의
상당부분을 서로 공유하는 경우가 많다. 만약 단지 자원을 읽어들이는 거라면 상관없지만 읽고/쓰는 것이라면 동기화와 관련된 문제가
발생할 수 있다.
예컨데 다음과 같은 경우다.
- A와 B 두개의 프로세스가 있다. 이 프로세스는 int count=1 이라는 자원을 공유한다.
- A가 count를 읽어들이고 1을 더한다.
- B가 count를 읽어들인다. 아직 A가 count에 쓰지 않았기 때문에, B도 1을 읽어들인다.
- A가 count에 2를 쓴다.
- B도 count에 2를 쓴다.
- count에는 2가 저장되었다.
우리가 원하는 값은 2가 아닌 3이다. 그러나 쓰레드가 동기화 되지 않음으로써, 원치않은 잘못된 연산을 하게 되었다. 우리는 이 문제를 해결해야 한다.
동기화 문제는 현실세계에서도 자주 발생한다. 화장실을 생각하면 된다. 화장실은 공유자원이며, 여러명이 사용한다. 누군가 화장실을 사용하고 있다면, 다른 사람은 화장실을 사용하면 안된다. 이 문제를 우리는 접근을 제어하는 방식으로 해결한다. 문을 걸어 잠궈서 한번에 한사람만 화장실에 들어가도록 하는 방법이다. 매우 이해하기 쉬운 방식이다.
다중쓰레드 프로그램에서도 마찬가지로 접근제어를 이용해서 이 문제를 해결한다. 이를 위해서 pthread는 mutex라는 잠금 메커니즘을 제공한다.
동시에 여러개의 쓰레드가 하나의 자원에 접근하려고 할때 발생하는 문제를 pthread는 임계영역을 두는 것으로 해결하고 있다. 임계영역안에는 접근하고자 하는 자원이 놓여있고, 오직 하나의 쓰레드만 임계영역안으로 진입할 수 있도록 제한한다. pthread는 이를 위해서 mutex를 제공한다. mutex는 그 자체가 가지는 잠금의 특성 때문에 mutex 잠금이라고 불리워지기도 한다.
위 그림은 mutex가 작동하는 방식을 보여준다. thread 1이 자원에 접근하면 mutex 잠금을 얻게 된다. 이 잠금은
단지 하나만 존재하기 때문에 thread 2는 잠금을 얻지 못하고 임계영역 밖에서 대기하게 된다. thread 1이 자원을 모두
사용하고 임계영역을 벗어나면 thread 2는 잠금을 얻게 되고 임계영역에 진입해서 자원을 사용할 수 있게 된다.
mutex를 사용하기 위해서는 다음의 4가지 함수가 필요하다.
- mutex 잠금객체을 만드는 함수
- mutex 잠금을 얻는 함수
- mutex 잠금을 되돌려주는 함수
- mutex 잠금객체를 제거하는 함수
1.8.3 pthread_mutex_init
mutex를 사용하기 위해서는 먼저 pthread_mutex_init() 함수를 이용해서, mutex 잠금 객체를 만들어줘야 한다.
pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutex_attr *attr);
이 함수는 두개의 인자를 필요로 한다.
- mutex : mutex 잠금객체
- mutex_attr : mutex는 fast, 'recursive, error checking의 3종류가 있다. 이 값을 이용해서 mutex 타입을 결정할 수 있다. NULL 일경우 기본값이 fast가 설정된다.
- fast : 하나의 쓰레드가 하나의 잠금만을 얻을 수 있는 일반적인 형태
- recursive : 잠금을 얻은 쓰레드가 다시 잠금을 얻을 수 있다. 이 경우 잠금에 대한 카운드가 증가하게 된다.
mutex_attr을 위해서 다음의 상수값이 예약되어 있다.
- fast : PTHREAD_MUTEX_INITIALIZER
- recursive : PTHREAD_RECURSIVE_MUTEX_INITIALIZER
- error checking : PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
1.8.4 pthread_mutex_lock
mutex 잠금을 얻기 위한 함수다.
int pthread_mutex_lock(pthread_mutex_t *mutex);
mutex 잠금을 얻는다라는 표현보다는 mutex 잠금을 요청한다라는 표현이 더 정확할 것 같다. 만약 mutex 잠금을 선점한 쓰레드가 있다면, 선점한 쓰레드가 mutex 잠금을 되돌려주기 전까지 이 코드에서 대기하게 된다.
때때로 잠금을 얻을 수 있는지만 체크하고 대기(블럭)되지 않은 상태로 다음 코드로 넘어가야할 필요가 있을 수 있을 것이다. 이 경우에는 아래의 함수를 사용하면 된다.
int pthread_mutex_trylock(pthread_mutex_t *mutex);
1.8.5 pthread_mutex_unlock
mutex 잠금을 되돌려주는 함수다.
int pthread_mutex_unlock(pthread_mutex_t *mutex);
1.8.6 mutex 잠금 예제
count 프로그램을 예제로 할 것이다. 임계영역안에서 보호되어야할 자원은 count이고, 여러개의 쓰레드가 count에 접근해서 +1을 시도하려고 한다. 이때 제대로된 count를 위해서는 한번에 하나의 쓰레드만이 counting을 하도록 해야할 것이다. mutex를 이용해서 임계영역을 보호하도록 할 것이다.
임계영역을 보호하지 않을 경우 다음과 같은 문제가 발생할 수도 있을 것을 예상할 수 있다.
int a = 1; Thread A 에서 a를 읽어들인다. Thread B 에서 a를 읽어들인다. Thread A 에서 a = a+1를 한다. { a = a+1; 결과는 2; } Thread B 에서 a++를 한다. { a = a + 1; // 읽어들인 값이 1이기 때문에 역시 결과는 2가 된다. }
두번의 count가 발생했기 때문에 3이되어야 하겠지만 임계영역이 보호되지 않음으로써 2가 되어 버렸다.
mutex는 임계영역을 잠금으로서 이러한 문제를 해결한다. 이러한 문제를 해결하기 위해서는 임계영역에 단지 하나의 쓰레드만 접근하는걸 보장해줘야 할 것이다. mutex는 아래의 요소들을 보장함으로써 이를 보장한다.
- Atomicity - mutex 잠금은 최소단위 연적 - atomic operation - 을 보장한다. atomic operation에 대해서 간단히 설명하고 넘어간다. 자세한 내용은
Atomic Operation을 참고하기 바란다.
- aotomic operation은 일련의 연산 즉 mutex 잠금 연산이 끝날때 까지 다른
프로세스가 그 연산의 변화를 알 수 없는 상태가 되는 연산을 의미한다. (일반적으로 연산은 이전의 연산의 결과를 관찰한 후에서야
이루어질 수 있게다)
- 전체연산중 하나라도 실패할 경우 모든 연산이 실패하며 시스템은 전체 연산이 시작하기 전의 상태로 복구된다.
- Singularity : 한 쓰레드가 뮤택스 잠금을 얻었다면, 이 쓰레드가 뮤택스 잠금을 내어놓기 전까지는 다른 쓰레드가 뮤택스 잠금을 얻을 수 없도록 한다.
- None Busy Wait : 이것은 성능과 관련된 것이다. 바쁜대기상태에 놓이지 않는다는 뜻이다. 뮤택스 잠금을 얻을 수 있는지를 확인하기 위한 연산이 필요하지 않는 다는 의미로 받아들이면 될 것이다.
이상 mutex는 위의 3가지를 지원하는 것으로 공유되는 자원을 충돌없이 그리고 효율적으로 사용할 수 있도록 보장해준다.
다음은 mutex를 사용한 count 예제프로그램이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| #include <stdio.h> #include <unistd.h> #include <pthread.h> int ncount; // 쓰레드간 공유되는 자원 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // 쓰레드 초기화 // 쓰레드 함 수 1 void* do_loop(void *data) { int i; pthread_mutex_lock(&mutex); // 잠금을 생성한다. for (i = 0; i < 10; i++) { printf("loop1 : %d", ncount); ncount ++; sleep(1); } pthread_mutex_unlock(&mutex); // 잠금을 해제한다. } // 쓰레드 함수 2 void* do_loop2(void *data) { int i; // 잠금을 얻으려고 하지만 do_loop 에서 이미 잠금을 // 얻었음으로 잠금이 해제될때까지 기다린다. pthread_mutex_lock(&mutex); // 잠금을 생성한다. for (i = 0; i < 10; i++) { printf("loop2 : %d", ncount); ncount ++; sleep(1); } pthread_mutex_unlock(&mutex); // 잠금을 해제한다. } int main() { int thr_id; pthread_t p_thread[2]; int status; int a = 1; ncount = 0; thr_id = pthread_create(&p_thread[0], NULL, do_loop, (void *)&a); sleep(1); thr_id = pthread_create(&p_thread[1], NULL, do_loop2, (void *)&a); pthread_join(p_thread[0], (void *) &status); pthread_join(p_thread[1], (void *) &status); status = pthread_mutex_destroy(&mutex); printf("code = %d", status); printf("programing is end"); return 0; } |
1.9 앞으로 할 것
쓰레드는 매우 광범위한 주제로 여기에서는 쓰레드를 사용하기 위한 가장 기본적인 내용만 다루었다. 쓰레드에 대한 좀더 자세한 내용은 별도의 장을 할애해서 다룰 생각이다.
:::

|