소프트웨어를 잘 만드는 방법

1. 소프트웨어를 만들려면 어떻게 해야 할까?

 

컴퓨터가 발명된 이래로, 프로그래머들은 어떻게 하면 프로그램을 더 잘 만들 수 있을까에 대해 고민해왔다. 초기에 베이직이나 코볼, 포트란으로 프로그램을 만들던 시절에는 서브루틴이라는 개념을 이용했고, 씨와 파스칼의 시대에는 모듈화라는 개념을, 그리고 c++ 의 시대에는 OOP의 개념을, 그리고 디자인 패턴과 컴포넌트 단위의 개발, 리팩토링, 테스트위주 개발에 이르기까지에 소프트웨어를 잘 만들기 위한 방법은 꾸준히 변화해왔다.

 

그러한 변화의 흐름속에서도 한가지 변하지 않은 기준이 있다. 그것은 바로 Divide and Conquer 라는 것이다. 완성된 소프트웨어라는 복잡한 목표를 달성하기 위해서는 어떻게 해서든 문제를 좀 더 작고 다루기 쉬운 단위로 나누어야 했고, 그 단위가 서브루틴, 모듈, 객체, 컴포넌트 등으로 변천을 거친 것이다. 물론 나누는 것만이 소프트웨어 공학의 전부는 아니고, 나눠진 것을 어떻게 조합할 것인가에 대한 것도 중요한 부분이라고 하겠지만, 어쨌든 소프트웨어의 부품이 이미 나눠져 있어야 그것을 조합할 수 있다는 것을 감안한다면, 앞으로 소프트웨어 공학이 어떻게 발전해갈지는 예측하기 어렵지만, 소프트웨어 공학의 본질에는 Divide And Conquer 라는 개념이 빠질 수는 없을 것이다.

 

그런데 문제는 소프트웨어를 나누는 방법은 한가지 방법만이 존재하는 것이 아니라, 실로 다양한 기준과 관점이 존재한다는 데에 있다. 어떤 기준과 목적을 가지고, 어떻게 나누느냐라는 것이 소프트웨어 엔지니어링의 본질이라고 보아도 과언이 아닐 것이다.

 

현대 소프트웨어 개발의 가장 큰 도전과제는 대형, 복잡화요구사항의 변동 2가지로 크게 나눌 수 있다. 2가지 과제에 잘 대처할 수 있는 소프트웨어를 만들 수 있도록 소프트웨어를 잘 나누어 놓는 것이 우리가 접근해야 할 길이며, 이 글에서는 그 해결방법으로서 변동성 중심의 디자인 해결방식을 제안할 것이다.

 

옛날의 소프트웨어 개발과 현재의 소프트웨어 개발의 가장 큰 차이점은 대형화, 복잡화라고 할 수 있다. 옛날에 80년대 컴퓨터들은 1Mhz 의 처리속도에 64Kb 의 메모리 용량을 가진 것이 보통이었다면, 지금은 3Ghz의 처리속도에 1GB 의 메모리 용량을 가진 것이 보통이 되어버렸다.

하드웨어가 발전하다보니 소프트웨어도 그만큼 발전을 하게 되었다. 컴퓨터의 성능이 남아돌게 되면서 예전에는 생각도 하지 못했던 기능들이 요즘에는 당연하게 기본기능들로 포함되고 있다. 컴퓨터의 가장 큰 용도중 하나인 워드프로세서의 경우를 보면 80년대에 가장 널리 쓰였던 워드프로세서의 경우 디스켓 한두장 분량에 들어가던 것이, 요즘 가장 널리 쓰이는 오피스류는 씨디롬 한장에 꽉 차게 되었다. 게임 같은 경우는 더 심해서 DVD 한장을 채우고도 남는 게임들도 종종 보이게 되었다. 기존에는 일반용 소프트웨어와 대형 (Large scale) 소프트웨어를 구분하는 것이 의미가 있었지만, 근래에는 대형소프트웨어라는 의미 자체가 무색해졌다. 모든 소프트웨어가 대형소프트웨어가 되어버렸기 때문이다. 그러다보니 업계경력이 10년 이상인 베테랑 프로그래머나, 이제 업계에 발을 들인 신입 프로그래머나 모두 똑같이 대형 프로그램을 짜는 법을 알아야만 하는 현실이 된 것이다. 심지어는 임베디드 환경 조차도 예전과 다르게 플랫폼이 점점 복잡화되고 있다.

대형 프로그램을 짜는 데에는 여러명의 공동 작업이 필수적이다. 예전에는 한 명의 천재 프로그래머가 대단한 프로그램을 만들어내는 것이 가능했고, 또 보통 소프트웨어는 그런식으로 만들어졌었다. 하지만 지금은 혼자서 대형 프로그램을 완성할 수 있는 경우는 드물다.

그런데 팀작업에는 한계가 있다. 프레드릭 브룩스가 그의 저서 The Mythical Man-month 에서 밝힌 것처럼, 소프트웨어를 만들 때에는 사람을 더 많이 투입할수록 그에 비례해서 개발기간이 단축되지 않는다. 그 이유는 작업자간의 커뮤니케이션 오버헤드는 사람이 많아질수록 기하급수적으로 늘어나기 때문이다. 팀작업을 하다 보면, 차라리 혼자 짜는 것이 낫겠다라는 푸념을 하게 되는 경우가 생기는 것이 그런 실제 예라고 할 수 있을 것이다.

처음에 말했듯이, 소프트웨어 공학의 원점은 Divide and conquer 이다. 소프트웨어를 어떻게 나눠야 사람들 간의 커뮤니케이션 오버헤드가 줄어들 수 있을 것인가? 이것은 대형 소프트웨어를 만드는 사람이라면 누구나 고민해보아야 할 주제이다.

 

 

2. 요구사항의 변동

 

커뮤니케이션이라는 것이 문제가 생겼을 때 모든 것을 정리해서 한번만 커뮤니케이션을 하고 끝낼 수 있는 성격의 것이라면, 아마 세상만사에 힘든 일이란 아무것도 없었을 것이다. 커뮤니케이션은 지속적으로 일어날 수 밖에 없다. 왜냐 하면 문제란 항상 변하기 때문이다.

어떤 특정한 고객의 요청을 받고 소프트웨어를 만들건, 기획팀이 대중들의 필요를 예상해서 소프트웨어를 설계하건, 프로그램팀 안에서 한쪽 모듈을 만드는 팀이 다른쪽 모듈을 만드는 팀에게 요청을 받아 모듈을 만들어주건, 모든 요청은 처음 한번으로 완벽하게 정해지고 끝나는 경우는 거의 없다. 왜냐하면, 문제해결의 과정에는 피드백이 계속 새로운 문제를 밝혀주기 때문이다. 어떤 문제가 제기 되어서 그에 대한 해답이 나왔다고 해도, 그 해답을 문제에 대입하면 새로운 문제를 발견하게 되는 것이 보통의 경우이기 때문이다.

요구사항의 변동은 결국 소프트웨어의 변동을 의미하고, 재작업 혹은 추가작업을 의미하게 된다. 하지만 소프트웨어를 어떻게 구성했느냐에 따라 요구사항의 변동이 생겼을 때 추가작업의 양은 많을 수도 있고, 적을 수도 있다. 소프트웨어를 어떻게 나눠야 요구사항의 변동에 더 쉽게 대응할 것인가? 이것이 이 글에서 논하고자 하는 문제의 요지이다.

 

다소 엉뚱하긴 하지만 자동차의 예를 들어보도록 하겠다. 차를 몰고 운전을 하다보면 이따금씩 벽이나 다른 자동차와 부딛혀서 긁히는 경우가 종종 있다. 그런데 대부분의 긁히는 부분은 범퍼에 해당되기 때문에, 많이 긁혔다고 하면 범퍼만 교환하면 된다. 범퍼는 재질이 철판이 아니고 더 싼 수지로 만들어져 있기 때문에 범퍼를 교환하는 비용은 다른 차체를 교환하는 비용에 비해 훨씬 싸다.

그런데 어떤 자동차가 있는데 범퍼와 차체의 구분이 없이 통째로 철판으로 만들어진 자동차라면 어떨까? 그런 자동차라면 앞부분을 살짝 긁혀도 범퍼만 가는 것으로 해결되는 것이 아니라 차체를 완전히 통째로 갈아야 하니 운전하는데 너무나 부담이 많이 될 것이다. 소비자의 입장에서는 두가지 차가 있는데 가격과 성능이 똑같다면 당연히 범퍼가 나뉜 쪽을 선호할 것이다. 소나타나 그랜져 같은 차는 여기에 한층 더 나아가서 범퍼 자체도 자주 긁히는 모서리쪽과 안쪽을 나눠서 모서리쪽에는 간단히 갈아낄 수 있는 다른 재질로 만들어놓았다. 웬만한 모서리는 긁게 되도 범퍼조차 갈지 않아도 되니 훨씬 더 경제성이 높아진 디자인이라고 할 수 있을 것이다.

 

위의 사례에서 접촉사고는 요구사항의 변동을 비유한 것이다. 접촉사고는 범퍼의 모서리, 범퍼, 차체의 순으로 빈도가 낮아진다. 소프트웨어를 만들 때에도 마찬가지로 모든 부분에 대해 요구사항이 변동되는 빈도가 같은 것이 아니라, 어떤 부분은 자주 변하는 반면, 어떤 부분은 자주 변하지 않는다. 그렇다면 소프트웨어를 어떻게 나눠야 할까? 답은 명백하다. 자주 바뀌는 부분과 자주 바뀌지 않는 부분을 경계로 나누어야 한다. 그렇게 했을 때 요구사항의 변동이 생기더라도(이것은 피할 수 없는 것이다), 그에 대한 대응이 훨씬 더 쉽고 빨라지는 것이다. (범퍼의 모서리만 바꾸는 것, 범퍼를 바꾸는 것, 차체를 통째로 바꾸는 것을 각각 비교해서 생각해보라)

 

 

3. 변동성의 원칙

 

모든 소프트웨어는 요구사항의 변동이 생길 수 있다. 요구사항의 변동 가능성을 간단히 줄여서 변동성 이라고 부르기로 하자. 이 변동성에 대해서는 몇가지 간단한 규칙들이 존재하는데 이것들을 알아보기로 하자.

 

l         소프트웨어의 각 요소의 유지 보수 비용은 변동성과 크기를 곱한 것이다

(크기가 큰 것이 변동성도 높다면 전체적인 유지보수 비용은 그 크기와 변동성에 각각 비례할 것이다)

 

l         프로젝트 전체의 유지 보수 비용은 소프트웨어 각각 요소의 유지 보수 비용을 합한 것이다

 

l         하나의 소프트웨어 요소 안에 변동성이 높은 부분과 변동성이 낮은 부분이 섞여 있으면, 전체 요소의 변동성은 높은 것으로 결정된다.

 

위의 경우는 자동차 범퍼의 예를 생각해보면 쉽게 이해가 갈 것이다. 차체와 범퍼가 구분되어 있지 않으면, 범퍼의 교체 비용이 차체까지 확산되는 것이다.

위의 3가지 사항을 합쳐서 생각해보면 한가지 결론에 도달 할 수 있다. 프로젝트 전체의 유지 보수 비용을 낮추기 위해서는 변동성이 높은 부분과 낮은 부분을 올바르게 나누어야 한다는 것이다.

숫자를 가지고 예를 들어보겠다. 소프트웨어 프로젝트를 A 파트와 B 파트로 나눌 수 있는데, A 파트의 크기는 10, 변동성은 20 이라고 하고, B 파트의 크기는 30, 변동성은 15 이라고 하자. 이 상태에서의 유지보수 비용은 10*20 + 30*15 = 650으로 계산할 수 있다. 만약 A B 가 나뉘어지지 않았다면 크기는 10+30 = 40, 변동성은 20 (20 15중 큰 것)이 되므로 유지보수 비용은 40*20 이 되어 800 이 된다.

그렇다고 해서 무조건 잘게 쪼개는 것만이 능사는 아닐 것이다. 소프트웨어를 쪼갤 때마다 조금씩 오버헤드가 생기기 때문에 너무 많이 쪼개는 것도 좋지 않다. 아까 자동차의 예로 돌아가서 생각해도 마찬가지다. 보통 자동차는 10장 내외의 철판, 범퍼등의 파트로 나뉘어져 있다. 만약 100 장 이상의 철판으로 잘게 나뉘어진 자동차를 상상해보라. 아마 자동차가 아니라 누더기가 되지 않을까?

 

l         변동성이 낮은 것이 변동성이 높은 것에 의존하면, 변동성이 낮은 것의 변동성이 그만큼 높아진다.

 

소프트웨어를 디자인하다 보면, 클래스 A가 클래스 B 를 의존 (참조, 상속, 등등) 할 것인가, 아니면 반대로 B A 에 의존하게 할 것인가, 아니면 다른 C 를 두어서, A B C 에 의존하게 할 것인가 같은 고민을 하게 되기 마련이다. 올바른 의존관계를 정의하는 데에 변동성은 이와 같이 좋은 기준이 될 수 있다.

변동성의 성격이 다른 부분이 섞인다는 것은 구체적으로 참조, 상속들의 의존관계가 맺어진다는 것을 의미한다. 의존관계는 변동성을 전염시킨다는 점은 매우 중요하다

 

l         변동성의 성격이 다른 부분이 상호 의존하게 되면 전체 요소의 변동성은 다른 변동성간의 조합만큼 높아진다

 

변동성을 고려할 때 단순하게 한 가지가 높다 낮다로서 판단될 수 있는 것은 아니다. 만약 변동성이 높은 요소 2가지가 혼재되어 있는 경우가 된다면 결과는 그 조합이 된다. 예를 들어 서로 다른 변동성이 10씩인 부분이 적절한 분리 메커니즘 없이 합쳐진다면 총 변동성은 10+10 = 20 이 아니라 10*10 만큼 높아진다는 점이다. 이런 경우의 디자인 목표는 어떻게 10*10 의 복잡도를 10+10의 복잡도로 낮출 것인가가 가장 중요한 이슈가 된다. 이후에 예제로 보는 부분들에서 그러한 복잡도를 낮추는 방법들을 구체적으로 알아볼 것이다.

 

l         변동성이 높은 부분은 재사용하기 어렵고, 변동성이 낮은 부분은 재사용하기 쉽다

 

OOP 를 비롯한 소프트웨어 공학의 근본목표는 소프트웨어 개발 비용을 줄이자는 것이고, 개발비용을 줄이는 방법으로는 소프트웨어 재사용을 장려하는 것이다. 그렇다면 재사용을 제대로 하기 위해서는 먼저 변동성에 대해 이해하는 것이 필요한 것이다.

 

변동성이란 개념은 아주 일반적인 개념이며, 자동차 범퍼의 예에서도 볼 수 있듯이 다른 일상 생활에서도 조금만 생각을 해보면 흔히 보거나 응용해볼 수 있는 개념이다. 책상정리를 할 때도 자주 사용하는 (변동성이 높은) 물건을 손 닿는 곳 가까이에 두고, 자주 사용하지 않는 (변동성이 낮은) 물건을 깊숙한 곳에 넣어두게 되는 습관이나 컴퓨터의 메모리나 CPU 에서 캐쉬메모리의 개념도 마찬가지로 변동성의 관점에서 생각해볼 수 있을 것이다.

 

 

4. 변동성의 분리 사례

 

지금까지 소프트웨어를 만드는 데에 소프트웨어를 부분별로 나누는 것이 왜 중요하고, 또 변동성이라는 개념이 소프트웨어를 나누는데 왜 중요한지에 대해 알아보았다. 이제부터는 좀 더 구체적인 실제 사례를 가지고 생각해보도록 하자. 위에서 언급했듯이, 변동성은 일반적인 개념이고, 사실 지금까지 당연히 쓰이고 있던 여러가지 컴퓨터 프로그래밍에 관련된 것들 속에도 변동성의 개념이 응용되고 있다는 점을 살펴보자.

 

i) 헤더파일과 소스파일의 분리

C 언어로 프로그램을 짜게 되면, 보통 헤더파일과 소스파일을 나눠서 짜게 된다. 어떤 기준에 의해서 헤더 파일에 들어갈 내용과 소스 파일에 들어갈 내용이 나뉘게 되는 것일까?

헤더파일을 나눈 이유는 다른 소스 파일들에서 공통으로 참조를 하기 위해서 나눠놓은 것이다. 이것은 다르게 말하면 소스파일들은 헤더파일에 같이 의존하고 있다고 할 수 있다. 변동성의 규칙중 의존에 대한 부분이 기억나는가? 변동성이 높은 것이 변동성이 낮은 것에 의존해야 유지보수비용이 낮아진다. 따라서 헤더파일에는 변동성이 낮은 내용(한마디로 자주 안 바뀌는 내용)이 들어가고, 소스파일에는 변동성이 높은 내용이 들어가야 한다.

이것을 지키지 않고, 단지 여러군데에서 공통으로 참조하기 쉽게 만들어버리면, 사소한 내용 하나를 바꿀때마다 관련된 모든 소스들이 재컴파일되므로, 빌드시간이 점점 늘어나게 된다. 빌드시간이 늘어나는 것을 해결하기 위한 올바른 해결책은 더 빠른 컴퓨터를 사용하거나 IncrediBuild 를 사용하는 것이 아니라, 변동성을 기준으로 헤더와 소스를 나누는 것이어야 한다. John Lakos Large Scale Software Design in C++ 에서 말하고자 하고 싶었던 내용이 결국 이 변동성에 대한 이야기인 것이다. 지금 당장 여러분 프로젝트의 헤더 파일을 잘 살펴보고, 변동성이 높은 부분이 들어있다면, 그것을 반드시 소스파일로 내려보내도록 하라. 그렇게 하기 위한 방법들은 여러가지가 있다.

 

ii) 외부용소스와 내부용소스의 분리 추상 인터페이스 or Pimpl idiom

여러분의 프로젝트는 추상인터페이스를 사용하고 있는가? 추상인터페이스 자체는 간단한 개념이다. 어떤 라이브러리에 사용되는 파일들 (소스와 헤더파일들)을 내부용과 외부용으로 분리하고 그 라이브러리를 사용하는 쪽에서는 외부용 파일만 참조하도록 만든 것이다. 내부용과 외부용은 물리적으로 아예 폴더 자체를 구분해 놓아야 한다. Directx 라던가 기타 라이브러리화가 잘 된 외부라이브러리를 보면 include 폴더와 src 폴더 (소스가 제공되지 않는 경우는 lib 폴더나 bin 폴더) 나뉘어져 있고 다른 소스는 include 폴더만 보면 되도록 구성되어 있다.

여기서 다시 질문, 라이브러리를 디자인 할 때, 어떤 파일이 내부용 폴더(src) 에 들어가고, 어떤 파일이 외부용 폴더(include) 에 들어가야 할 것인가? 역시 그에 대한 해답의 열쇠는 변동성의 개념이 쥐고 있다.

일단 소스 파일들은 변동성이 높은 것들이라는 점을 위에서 말한 바 있다. 그러니 모든 소스 파일들은 내부용 폴더에 넣고, 외부의 사용자들은 신경쓰지 않게끔 만들어야 한다.

그 다음은 헤더파일들이다. 헤더파일들이 모두 외부용 폴더에 들어가게 만들 수도 있다. 하지만, 모든 헤더파일들이 외부의 사용자들에게 꼭 필요한 것은 아니다. 외부의 사용자들은 내부가 어떻게 구현되었는가 보다는 어떻게 사용하면 되나 만 알면 되기 때문이다.

어떻게 사용하면 되는가? 라는 것이 바로 인터페이스(Interface)이고, 내부가 어떻게 구현되었는가? 는 바로 구현(Implementation) 이다. 인터페이스와 구현중, 어떤 것이 변동성이 높고, 어떤 것이 변동성이 낮아야 할까? 물론 인터페이스가 낮고, 구현이 상대적으로 높아야 한다.

만약에 인터페이스의 변동성이 더 높다고 하면 아직 인터페이스가 안정화되지 못한 상태 아니면, 인터페이스를 잘못 만든 경우 둘중의 하나라고 볼 수 있다.

추상 인터페이스는 하나의 클래스를 인터페이스 (흔히 I 로 시작되는 클래스명) 와 구현 클래스 (흔히 C 로 시작되는 클래스명) 로 분리해서, 외부의 사용자는 인터페이스만 include 해도 되도록 만드는 기법이다. 만약에 인터페이스와 구현을 클래스를 분리해놓고도 물리적으로 폴더를 나눠놓고 외부헤더만 액세스하고 있는 것이 아니라면 추상 인터페이스를 제대로 쓰지 못하고 있는 것이다 (필자가 본 중에는 그런 케이스가 있었다)

추상인터페이스 라는 기법 자체는 외부폴더와 내부폴더를 나누기 위한 방법(물론 전체적인변동성을 낮추기 위한)중 하나에 불과한 것이다. 추상 인터페이스는 클래스의 상속을 이용해서 구현과 인터페이스를 분리한 것이라면 Pimpl 방식은 클래스의 조합을 이용하여 구현과 인터페이스를 분리한 것이며, 본질적으로는 동일한 목적과 유사한 결과를 가져다준다.

 

iii) 데이터 타입과 알고리즘 코드의 분리 - Template

어떤 알고리즘과 그 알고리즘의 대상이 되는 데이터 타입도 마찬가지로 나눠놓게 되면 각각의 경우에 따라 변동성을 낮출 수 있다. 예를 들면 정수를 대상으로 퀵소트를 하는 함수를 만들었다고 하자. 퀵소트의 알고리즘 자체가 변동성이 높은가? 정수라는 타입의 변동성이 높은가? 퀵소트를 놓고 보면 당연히 정수라는 타입의 변동성이 높다. 퀵소트의 구현 방법 자체는 수십년전에 만들어져서 지금까지 거의 비슷하게 사용되고 있는데, 퀵소트의 대상은 정수, 실수, 문자열등 다양한 대상이 될 수 있다. 퀵소트뿐만 아니라 어떤 일반적인 풀이법을 놓고 볼 때 알고리즘과 데이터는 서로 변동성이 다르기 때문에 분리할 수 있다면 알고리즘 자체의 재사용성을 높일 수 있다. 이 경우에는 한쪽의 변동성이 높고, 다른 한쪽의 변동성이 낮은 경우라기 보다는 서로 성격이 다른 변동성이 조합되는 경우로 보아야 할 것이다.

자 그러면 여기서 퀴즈. C++ 이 제공하는 알고리즘과 타입을 분리하는 메커니즘은 무엇일까?

정답은 템플릿이다. 템플릿은 generic programming 의 가장 중요한 도구이다. Generic 은 말 그대로 프로그램에서 일반적으로 사용될 수 있는 요소를 추출해내서 그 부분을 모아놓는 것인데, 여기서도 변동성의 개념이 연관되어 있는 것을 알 수 있다.

이러한 알고리즘들을 변동성이 높아지지 않는 형태로 재사용하는 사례중 가장 대표적인 것은 STL 이 제공하는 각종 알고리즘들이다. STL 이 제공하는 알고리즘을 사용하기 위해서는 아무 데이터 타입을 넣을 수 있는 것은 아니고 몇가지 요구조건을 만족해야 하는데, 대표적인 것이 < 연산자를 정의하는 것이다. 연산자 혹은 Functor 라는 중간 방벽을 둠으로써, 알고리즘이 달라지건, 알고리즘이 다룰 데이터 타입이 달라지건 그 조합만큼 코드가 늘어나는 것을 피할 수 있다는 것이 STL 알고리즘의 가장 큰 장점이다

 

iv) 데이터와 코드의 분리 Data-driven design

데이터와 코드, 둘중 변동성이 높은 것은? 데이터다. 그렇다면 데이터와 코드를 분리하면 변동성이 낮아지고 유지보수에 도움이 될까? 물론이다. 우리는 그것을 Data-driven Design 이라고 부른다.

모든 데이터가 처음부터 코드와 분리되어 보이는 것은 아니다. 숫자나 문자열이라고 해서 모두 데이터는 아니기 때문이다. 코드에서 모든 데이터를 어떤 기준없이 죄다 빼내려고만 한다면, 무엇이 목표인지 조차 모호하게 되어버릴 것이다. 데이터를 나눠내는 그 기준은 물론 변동성이어야 한다. 같거나 비슷한 코드에 데이터만 바뀌어가면서 반복되는 부분, 바로 그런 부분을 추려내는 작업은 리팩토링의 큰 부분을 차지한다.

 

v) 스크립트 코드와 소스 코드의 분리 Lua, Python,

코드중에도 명백히 변동성이 높은 코드가 있는가 하면, 변동성이 낮은 코드가 있다. 변동성이 높아서 Data 로 분리하고 싶긴 한데, 단순한 데이터가 아니라 어느정도 판단 로직이 있기 때문에 데이터로는 분리하기 쉽지 않은 그런 것들은 어쩔 수 없이 코드의 형태로 존재할 수 밖에 없는 것들이다.

가장 대표적인 예는 RPG 에서 NPC 의 대사 스크립트 같은 부분들이 될 것이다. 어떤 물건을 가져왔으면 A 이벤트로 넘어가고, 그렇지 않으면 B 로 넘어가게 만드는 그런 코드들과 화면에 물체를 그리고 키보드 입력을 받는 그런 코드들은 근본적으로 변동성이 다를 수 밖에 없다.

이러한 변동성이 높은 코드들이 소스 안에 변동성이 낮은 코드들과 함께 존재한다면 역시 프로젝트의 유지보수비용이 증가하게 된다. 그 해답은 바로 스크립트 분리 이다.

 

vi) 패턴화된 코드의 집합과 어플리케이션 특정 코드의 분리 프레임워크

윈도우 프로그래밍의 세계를 접하게 되면서 프로그래머들은 많은 어려움을 느끼게 되었다. 단적인 예로 Hello world 같은 프로그램을 만드는 데에 DOS 같은 경우는 몇줄이면 충분했지만 윈도우의 세계로 오면서 몇줄은 커녕 몇백줄의 복잡한 windows API 를 제어하는 코드를 Event-Driven 이라는 기존과는 다른 생소한 방식으로 짜야만 했다. 그에 따르는 복잡도의 증가와 개발의 어려움이 이만저만이 아니었기에 OWL 이나 MFC 같은 프레임워크가 등장하여 프로그래머의 어려움을 덜어주었다.

프레임워크는 복잡한 윈도우 응용 프로그램의 소스코드중에서도 자주 바뀌는 부분과 자주 바뀌지 않는 그래서 재사용가능한 부분이 있다는 통찰에서 비롯된 산물이다. 물론 프레임워크 자체도 변동성이 낮다고는 볼 수 없다. MFC 같은 라이브러리도 컴파일러가 바뀌면서 계속 변화하고 발전해왔다. 하지만 어플리케이션 자체보다는 상대적으로 변동성이 낮았기 때문에 프레임워크로서의 가치가 있었던 것이다.

 

SideNote

여담으로 개인적인 얘기를 몇마디 하고자 한다. 지난날 MFC 가 계속 변화해오던 불안정했던 시기나, Direct3D 가 계속 변화해오던 시기를 생각해보면, 필자는 공통적으로 그때 MFC Direct3D 용 프로그램을 만들지 않았었다. 오히려 더 이전시대의 기술인 DOS GDI 를 이용한 프로그램을 만드는 것을 더 선호했었고, D3D MFC 에 대한 막연한 거부감을 가졌었는데 지금 돌이켜보면 분명하게 그 이유를 말할 수 있을 것 같다. 신기술이기 때문에 사용하기 꺼린 것보다도, 변동성이 높기 때문에 사용하기 꺼린 것이다. 개발자들이 안정적으로 프로그램을 만들기 위해선 안정적으로 의존할 수 있는 대상이 있어야 하며 그 대상은 반드시 변동성이 낮아

imcgames 의 김학규입니다

댓글
2005.07.24 14:56:30 (*.104.88.252)
[레벨:13]neolith
예전에 썼던 글을 HTML 로 좀 더 보기 좋게 편집하고 내용을 보강한 버전입니다
삭제 수정 댓글
2005.07.24 17:21:41 (*.114.195.127)
페트로스
콘솔 게임기는 타 하드웨어에 비해 변동이 적군요. 한번 나오면 5년 이상은 버텨주니까....
삭제 수정 댓글
2005.07.24 19:25:31 (*.85.32.218)
모자장수
오잉? 이거 읽었던 거 같은데? 하니, html 로 다시 쓰신 글이군요. 멋진 글 감사합니다.
삭제 수정 댓글
2005.07.25 13:18:33 (*.85.18.172)
지나가다
제목만 보고..
소프트웨어를 잘 만드는 방법 에 대해
변동성 이란 사람이 글을 쓴 줄 알았다는;;
댓글
2005.07.26 12:23:31 (*.148.103.76)
[레벨:2]eriastoa
지나가다님 대박이시다. 박장대소 올인 >.<;;
댓글
2005.07.28 21:14:35 (*.69.185.165)
[레벨:2]baboneo
좋은 글 감사합니다. 스크랩 할께요~ ^^
댓글
2005.09.09 00:52:23 (*.230.154.15)
[레벨:4]강홍기
이글을 읽고, 평소에 무의식적으로 행동했었던것을
머리속에서 잘정리 할수있었습니다.
나의 소셜 정보
  • XE Login
  • 트위터 Login
  • 미투데이 Login
  • 페이스북 Login
  • 요즘 Login
  • 원하시는 로그인을 선택해주세요
powered by SocialXE
번호
제목
글쓴이
공지 저의 약력과 구글 프로필 4 226
[레벨:13]채이도훈아빠
370150 43 2010-02-11 2014-02-15 12:57
공지 내가 읽었던 좋은 책들 64 248
[레벨:13]neolith
425153 529 2002-12-20 2011-12-05 15:01
440 XL1200R 사진 30 71 file
[레벨:13]neolith
30598 211 2005-08-03 2005-08-03 15:55
OHV 4stroke, 45' V-twin, air-cooled, 1202cc, Rubber-Mounted Engine 빨리 머플러를 갈지 않으면 안되겠다는 생각이... 아 그리고 헬멧이나 슈트, 부츠 같은 종류 취급하는 괜찮은 숍 좀 소개 부탁드립니다. 할리 매장은...  
439 물반사에 대해 알려주세요. ^^ 1
[레벨:2]러브
30569 124 2003-04-09 2003-04-09 13:04
최근 리니지2를 보니 바다를 표현하는데... 지형이 반사된 장면을 반영하여 굴절까지 되어 표현 되어 있더라고요. 이를 표현하려면 어떻게 해야할까요. D3D에서 하려면 아래와 같이 하면 될까요? 1. 물의 높이와 같은 넓은 판(P...  
438 시맨틱 웹 - 김중태 지음 23
[레벨:13]neolith
30549 80 2006-02-27 2006-02-27 02:28
http://www.aladdin.co.kr/shop/wproduct.aspx?ISBN=8995527625 강력 추천 도서  
437 오카모토 요시키의 독립 회사 19
[레벨:13]neolith
30520 96 2003-07-01 2003-07-01 20:35
http://okatuku.ciao.jp/index.html 번역기로 돌려서 읽어보고 있노라면 상당히 정감가는 아저씨임에 분명 빌로퍼도 블리자드에서 독립하고, 오카모토 요시키도 캡콤에서 독립하고 뭔가 업계가 술렁술렁하는 느낌이 많이 드네요. 게임제작...  
436 두개의 d3dDevice생성에 대한 문제.. 2
[레벨:2]오명근
30506 510 2003-05-10 2003-05-10 01:28
안녕하세요. 저번에 가르쳐주신대로 2개의 리스트를 만들어서 DrawPrimitive에 대한 문제를 해결했습니다. 감사드리구요, 궁금한게 하나 생겨서 질문을 올립니다. 제가 만들고 있는 맵툴은 MFC기반인데요 우선 기본 뷰에서 CEngin...  
435 우리 회사 안에 들어오게 하고 싶지 않은 사람의 유형 58
[레벨:13]neolith
30473 219 2004-03-10 2004-03-10 01:12
1. 신용이 없는 유형 (자기관리가 되지 않는 사람) 기본적으로 뭘 해도 위험하다. 돈을 빌리면 돈을 갚지 않고, 카드를 쓰면 카드를 연체시키고, 작업이 할당되면 작업시간을 어기고, 프로그램을 짜면 버그를 만들고, 그림을 그...  
434 서점의 베스트셀러 가판대와 자본주의 26 4
[레벨:13]neolith
30449 89 2005-12-18 2005-12-18 22:47
문득 생각이 난 것인데.. 서점에 가면 베스트 셀러 (1위부터 20위까지)를 따로 진열해놓은 코너가 있다. 나같은 사람을 비롯해서 많은 사람들은 베스트셀러 순위에 영향을 받는다. 어떤 책이 베스트셀러가 되면, 베스트셀러라는 이...  
433 시골의사의 부자경제학 한줄 요약 47 14
[레벨:13]neolith
30400 102 2006-11-27 2006-11-27 20:56
'재테크 같은 것에 부화뇌동하지 말고 자기 자신에 투자해라'  
432 나의 애마를 소개합니다 - 2 8 file
[레벨:13]neolith
30383 101 2004-10-31 2004-10-31 17:41
휠은 Shuk (예전 ASA 라는 브랜드로 판매되던 한국타이어에서 만드는 휠의 새로운 브랜드. ) 너무 요란하지 않으면서 중후한 맛과, 광택이 잘 살아나는 재질등이 마음에 든다. 슈크라는 이름도 그다지 맘에 드는건 아니지만, ...  
431 어느게 더 빠를까요 2
[레벨:2]고경석
30347 109 2003-06-29 2003-06-29 15:06
텍스쳐소팅 VS Z소팅 물론 2가지 다 사용하면 좋겠지만 현실적으로 불가능한거 같습니다 구조에서부터 틀린것 같습니다 여기서 제가 말하는 텍스쳐소팅은 맵이나 오브젝트의 메쉬를 폴리곤 단위까지 분해하여 사용되는 텍스쳐별로 ...  
430 대강 여기꺼정요.. 나머진 또 잘라서 번역 --; 77
[레벨:2]kyunghuns
30337 116 2005-06-15 2005-06-15 17:57
>http://www.sijimi.net/online/sb.cgi?eid=362 > >누가 해석좀 부탁... 윗부분 : 6월10일 있었던 그라나도에스파다 기자발표회의 대충리포트 입니다. 어젯밤 정도에 (리포트를) 보여 드릴 수 있을까 말을 했었엇는데 못했습니다. ...  
429 싸우고 지는 사람, 싸우지 않고 이기는 사람 12 19
[레벨:13]neolith
30328 86 2004-07-30 2004-07-30 12:26
근래 샀던 책 중 꽤 느낌이 좋았던 책이라 독후감을 남깁니다. 제목 : 싸우고 지는 사람, 싸우지 않고 이기는 사람 지은이 : 송병락 삽화 : 이원복 출판사 : 청림출판 이 책은 '전략'에 대한 책이다. 전략이라는 이름만 들...  
428 소프트웨어 프로젝트에서의 리스크관리 15 40
[레벨:13]neolith
30294 81 2004-09-25 2004-09-25 00:49
톰 디마르코와 티모시 리스터는 프로젝트를 추진하는 사람에게는 정말 소중한 조언자다. 그들은 언제나 이상과 이론의 세계가 아니라 현실과 실제의 세계에서 필요한 살아 숨쉬는 조언을 전해준다 '피플웨어' 가 인간적인 조직을 ...  
427 Thoughts - 모든 프로그램은 데이타베이스의 일종이다 3 12
[레벨:13]neolith
30285 96 2004-09-26 2004-09-26 23:22
1. 모든 프로그램은 데이타베이스의 일종이다. or 데이타베이스를 가지고 있다 * 게임이건 워드프로세서이건, 어떤 데이타들을 가지고, 그것을 처리하는 일을 하고 있다 * MVC 구조의 Model, 혹은 Document-View 구조의 Documen...  
426 냉정과 열정사이 ... -_-;; 3
[레벨:2]오픈헤드
30284 253 2003-10-09 2003-10-09 18:42
영화는 아니다 -_-;; 지금도 고민하고 있다. 열정만으로 지금처럼 공동의 꿈과 개인의 꿈을 위해 밤을 새우며 건강에 문제가 생겨도 진행해야 하는것인가 아니면 냉정을 찾고 몸을 추스리는 것이 올바른 것인가. 무리하게 일들을 ...  
425 꼴찌, 동경대 가다! 9 11
[레벨:13]neolith
30242 3 2008-01-15 2008-01-15 00:49
학습을 소재로 한 만화. 머니의 켄 작가가 그린 다른 만화를 찾다가 우연히 알게 되었는데 볼 수록 감탄사가 나온다. 특히 입시를 앞두고 있는 학생들에게 권하고 싶다... 라고 말하고 싶지만 실은 직장인들에게 권하고 싶다. ...  
424 거짓말 31 20
[레벨:13]neolith
30228 85 2004-07-10 2004-07-10 06:35
많은 청소년들은 어머니가 무언가 새로운 것을 먹이려고 할 때 '이거 맛있는거야' 라고 하면서 음식을 입에 갖대대면 무의식적으로 고개를 돌리는 경향이 있다. 그 이유는 어렸을 때 어머니가 소 간이나 개불, 개고기, 괴이한 ...  
423 프로페셔녈 소프트웨어 개발 中..
[레벨:2]팬다맨
30227 253 2003-12-22 2003-12-22 03:47
요즘 읽고 있는 책 입니다만.. ( 개발자 보다는 교육자 위주의 책인거 같음 ) 개인적으로 재미있다고 생각되는 구절을 옮겨오겠습니다. ========================================================================...  
422 나의 애마를 소개합니다 - 3 10 18 file
[레벨:13]neolith
30181 100 2004-10-31 2004-10-31 17:50
실내에는 Clarion MP3 오디오 플레이어와 게이지 2 개가 특이사항의 전부 개인적으로 차 안에는 요란하게 네온켜놓고 완전 살림집 꾸미듯이 이것저것 몸에 좋다는 것은 다 붙여 놓는 쪽은 절대 기피하는 체질. 게이지도 튜닝...  
421 San Francisco 에서 만난 기자 이야기 17
[레벨:13]neolith
30166 29 2007-02-17 2007-02-17 11:54
미국에서 그라나도 (여기 이름은 Sword of the new world) 소개차 미디어 이벤트를 위해 샌프란시스코에 왔습니다. 정말 경치도 좋고 멋있는 곳입니다. 사진은 귀국후 정리해서 올리도록 하고... 이벤트에서 만난 게임 디벨로퍼...  
420 윈도우즈 비스타 + xNote S900 9 11
[레벨:13]neolith
30013 3 2007-10-18 2007-10-18 13:10
회사에서 세컨드 컴으로 쓰려고 이번에 s900 을 구매하였다. 더욱 애자일한 개발환경을 만들려면 어떻게 해야 할까에 대해서 고민하던차, 특히 페어 프로그래밍을 권장하는 개발환경을 만들려면 어떻게 하는 것이 좋을까에 대해서 ...  
419 갤러리의 스타크래프트 옛날 화면을 보고 27
[레벨:13]neolith
29990 95 2004-01-06 2004-01-06 01:05
갤러리에 보면 스타크래프트 옛날버전에 대한 스크린샷 모음들이 올라와있다. 스타를 좋아하는 사람이라면 누구나 관심을 가질만한 흥미로운 내용이기도 했지만, 국내에는 잘 소개되지 않은 미국식 프로페셔널한 게임제작방법의 핵심기...  
418 Amazon Kindle 4 14
[레벨:13]neolith
29984 3 2008-04-20 2008-04-20 19:03
http://www.amazon.com/gp/product/B000FI73MA 한국에서도 되면 좋을텐데.. 핸드폰식 wifi 인 것을 보니 좀 먼 듯  
417 이니셜 D OST 의 뒤를 이어가는 레이싱용 음악 추천 19 175
[레벨:13]neolith
29980 134 2004-11-30 2004-11-30 12:29
Burnout 3 - Take Down OST 아 번아웃 게임도 너무 좋고 음악도 너무 좋다. EA 같은 개발사니까 만들 수 있는 것이랄까 나 이러다 EA 빠돌이 될 듯 (NFS, 007 Everything or Nothing 이후 3연속 콤보중) 암튼 절로...  
416 심시티가 만들어지게 된 배경 29
[레벨:13]neolith
29975 20 2007-02-20 2007-02-20 14:42
EA에서 일했던 개발자와 얘기하면서 듣게 된 내용입니다. 원래 도시 폭격하는 게임을 만들면서 도시 디자인하는 에디터를 만들었었는데, 도시 만드는 에디터 갖고 노는게 생각보다 재미있어서 이것저것 기능을 붙이다보니까... 도시...  
415 구글 애드센스 장착 19 2
[레벨:13]neolith
29941 68 2007-01-22 2007-01-22 15:29
웹 2.0 시대에 즈음하여 본 사이트에도 시험삼아 구글광고를 달아보기로 하였습니다.  
414 새로운 책 소식들 4 종 7 1
[레벨:13]neolith
29913 96 2003-07-22 2003-07-22 10:42
Microsoft Directx9 Programmable graphics pipeline - Kris Gray, Microsoft press VertexShader, PixelShader, HLSL, Effect Framework 에 대해 다룬 책 Applied C++ - Philip Romanic, Amy muntz, Addison wesle...  
413 텍스쳐 색깔 입히기에 대한 질문입니다.. 2
[레벨:2]오명근
29835 299 2003-06-19 2003-06-19 15:33
제가 맵툴을 하나 만들어보고 있는데요 맵을 만들고 각 타일별로 속성을 주려고 하고 있거든요. 음.. 그러니깐 갈 수 있는곳은 0, 없는곳은 1 뭐 이런식으로 주려고 하는데 문제는 제가 마우스로 클릭해서 타일들의 속성을 바꿔...  
412 쓸만한 무료 일정관리 프로그램 3 2
[레벨:13]neolith
29825 122 2003-04-05 2003-04-05 22:24
http://www.palm.com/support/downloads/win_desktop.html 아웃룩과 유사한 시스템을 갖추고 있지만 아웃룩보다 가볍고, 쓸데없이 연동되는 것이 없는게 오히려 더 좋습니다. 팜 PDA 를 갖고 있는 사람과의 연동을 위해 만들어진 프로...  
411 MMORPG 에 더 이상 혁신이 남아있을까요? 없을까요? 69 3
[레벨:13]채이아빠
29803 11 2009-09-22 2009-09-22 00:50
만약, 자신이 종사하는 분야에 더 이상 혁신의 거리가 남아있지 않게되었다고 하면, 창의적인 인재에게는 종말이나 다름없는 상황이겠죠. 앞으로 MMORPG 에 어떠한 혁신의 기회가 남아있을까요? 게임 시스템 적인 것이건 (레이드...  
410 일본에 강연하러 갑니다 30 2
[레벨:13]neolith
29801 98 2004-08-15 2004-08-15 18:31
9월 6일 예정입니다. http://cedec.cesa.or.jp/session/9_6.html 강연후에 강연하고 난 자료는 한국어판으로 이곳에도 올리겠습니다.  
409 [re] 해석-02 1 81 file
[레벨:2]글로리ㅡ3ㅢv
29765 101 2005-06-15 2005-06-15 23:41
>http://www.sijimi.net/online/sb.cgi?eid=362 > >누가 해석좀 부탁...  
408 근하신년 27 10 file
[레벨:13]neolith
29762 102 2007-01-01 2007-01-01 00:13
사진 1: 2006년 마지막 석모도의 일몰 사진 2: 추암 촛대바위의 일출 개인적으로도 정말 많은 일이 있었던 한 해였습니다. 2007년은 어떤 해가 될지 궁금합니다. 여러분들 2007년 한해에 소망하신 것들 많은 성취 있으시길 기...  
407 GeForce3 프로그래밍 FAQ - Performance 편 1
[레벨:13]neolith
29727 136 2003-04-17 2003-04-17 19:43
Vertex Shaders 23. 버텍스 쉐이더의 명령 갯수와 수행 성능과는 어떤 관계가 있습니까? 답) 버텍스 쉐이더의 수행성능은 명령의 갯수가 늘어나는 만큼 선형적으로 영향을 받습니다. 대체적으로 명령어 한개당 한개의 명령싸이클...  
406 변동성과 소프트웨어 공학 3 98
[레벨:13]neolith
29720 76 2004-06-08 2004-06-08 19:00
http://www.lameproof.net/wiki/wiki.php/%C1%C1%C0%BA%BC%D2%C7%C1%C6%AE%BF%FE%BE%EE%B5%F0%C0%DA%C0%CE  
405 아마존의 컴퓨터 책들 뒤지다가 발견한 어떤 서평 3 63
[레벨:13]neolith
29714 10 2008-12-15 2008-12-15 23:48
별 한개짜리 평가에 다른 사람들이 대체로 동의 (47명중 45명) 하는 경우는 많지 않은데, 서평이 재밌어서 퍼서 번역해봄 대상은 Pro OGRE 3D Programming (Hardcover) 라는 책임. --------------- 제목 : '어떻게 이런 책이 출간...  
404 자식 자랑은 팔불출이나 한다지만 26 11 file
[레벨:13]neolith
29712 4 2007-10-22 2007-10-22 22:04
두장 올려봅니다 완소 채이 무보정 리사이즈 20% 위 사진은 5D에 100mm 마크로로, 아래 사진은 5D에 50mm 1.4 로 찍었습니다. 아래 사진이 특히 실내 자연광으로 찍었는데 피부색이 아주 맘에 들게 잘 나왔습니다. 요즘은 5...  
403 8.0 과 9.0 사이에 고민 ㅡ_ㅡ; 무얼쓰는게 좋을까요.. 2
[레벨:2]봄소풍
29704 165 2003-08-08 2003-08-08 16:29
학규님 오랜만에 인사드립니다.. __) 그동안 안녕은 하셧는지;;;; 요번에 저희가 새로 프로젝트를 들어가는데요. 그동안 쭈욱 8.0으로 작업을 했는데 이번에 9.0이 나와서 고민중에 있거든요. 궁금한것은 8.0과 9.0의 장단점과 9.0을...  
402 2006년 게임대상 대상수상 감사 48 file
[레벨:13]neolith
29670 111 2006-12-18 2006-12-18 22:24
개발을 한지 10년이 넘었지만 개인적으로 상과 인연이 별로 없었는데, 큰 상을 받게 되어 너무나 감사하고 영광으로 생각합니다. 가장 먼저 게임이 나오기도 전부터 많은 관심과 격려, 성원을 보내주신 유저여러분께 감사의 뜻...  
401 Thank you for smoking 7
[레벨:13]neolith
29643 14 2007-03-07 2007-03-07 20:45
마누라와 함께 본 바벨의 충격 (허탈과 돈 아까움의)이 채 가시지 않은 상태.. 거뭇거뭇한 중년남이 권해서 ('최대한 기대하지 말고 보기 바란다') 본 영화 소감 :'졸라짱! 이건 내용이 코메디라고 하기엔 진지하고, 다큐멘터리라...  
400 양떼목장 22 file
[레벨:13]neolith
29641 105 2007-01-04 2007-01-04 03:33
아내와 함께 찾아갔었던 대관령 양떼목장 살을 에는 듯한 산바람과 함께 원없이 눈밭을 거닐며 설국의 분위기를 느낄 수 있었다. 봄이 지나 잔디가 푸르러지고 나면 꼭 다시 찾아오고 싶은 곳이다.  
399 XP (Extreme Programming) 에 대한 잡생각 7 1
[레벨:13]neolith
29612 99 2006-10-16 2006-10-16 21:33
XP 라는 것을 처음 접하게 되었을 때 첫 인상은 솔직히 좋지가 않았다. 그 내용은 둘째치고 제목이 익스트림 프로그래밍. 한글로 번역하면 '존내 프로그래밍' 인건가? 근데 막상 내용을 보면 존내 프로그램짜는거랑 성격도 다...  
398 OO Programming - 상속의 남용을 막자 19 140
[레벨:13]채이도훈아빠
29610 16 2010-01-05 2010-01-05 18:45
아주 간단한 GUI 예제 프로그램을 만든다고 생각해보자. 기본 윈도우 위에 버튼이 하나 배치되어 있고, 버튼을 누르면 "Hello" 라는 팝업 윈도우를 띄워주는 프로그램이다 버튼 하나와 윈도우 하나가 들어가는 아주 간단한 예제...  
397 이사를 가고 인터넷을 끊다 34 81
[레벨:13]neolith
29536 96 2004-11-29 2004-11-29 11:53
며칠전 이사를 했다. 그렇게 멀지는 않은 우면동 안쪽, 산으로 둘러쌓여 서울 안에 있는 집이라곤 믿어지지 않을 정도로 공기가 좋은 곳이다. 물론 이사 이유는 공기가 나쁜 환경을 벗어나보려는 의도에서다. 얼마전부터 병원치료...  
396 KGC 2004 강연 대본 완전판 16 15
[레벨:13]neolith
29520 144 2004-10-20 2004-10-20 18:57
동영상이 삭제된 대신 무슨 내용이 있었나 궁금하실 분을 위해서 본 스크립트를 올립니다. 참고로 제가 이 스크립트를 보고 강연을 읊은 것은 아니고, 어떤 사람이 제 동영상을 보고 일일이 녹취를 해서 만들어서 보내준 것입니...  
395 어제를 돌아보며 오늘을 생각한다 28
[레벨:13]neolith
29512 57 2006-08-11 2006-08-11 15:33
자뻑일지 모르겠지만 내가 옛날에 게시판에 쓴 글들을 다시 하나씩 읽어보고 있으면 꽤 괜찮은 글들이 많다. 내가 쓰고 말한거만이라도 잘 지키도록 노력해야겠다.  
394 제주도 여행기 6 - 산굼부리 분화구 4 105 file
[레벨:13]neolith
29499 159 2004-04-05 2004-04-05 14:28
산굼부리 분화구에 도착. 옛날에는 활화산 분화구였던 곳이라고 한다. 걸어가면서 둘러보고 있노라면 주위의 풍경이 2중스크롤 된다.  
393 석모도 7 file
[레벨:13]neolith
29484 93 2007-01-04 2007-01-04 03:26
2006년 마지막 일몰을 찍으려고 찾아갔던 석모도... 하지만 강화도에서 배를 타고 건너가서 해변가로 달려가는 사이 이미 해는 저물고 아쉬운 마음에 해진 방파제를 찍고 돌아오다  
392 경영관련 - 아이러스스쿨은 왜 잊혀졌는가 4 file
[레벨:2]박기주
29433 88 2003-10-02 2003-10-02 16:22
많이들 보신 글이겠지만 저는 최근에 읽었습니다. 다른 분들도 보시는 게 어떨까 싶어 늦은 자료지만 올립니다. 미리 게시된 글이면 양해를.... (이 많은 게시물을 다 읽은 순 없군요.) zayro  
391 GE 로그인 음악 피아노 연주 29
[레벨:13]neolith
29431 130 2006-11-14 2006-11-14 12:31
http://cyplaza.cyworld.nate.com/bbs/bbs_view.asp?BoardCode=107&subBoardCode=14&ItemNum=20061004145512325517 색 다른 느낌. 템포가 약간 빠른 면이 있는데, 이는 연주자의 해석에 따라 달라질 수 있는 면 (빨리 로긴하고 싶다) ...