2005년 09월 02일
객체지향에 대한 나름의 해설
Kay's Description of OOP
무표정군의 블로그에서 트랙백 합니다.
오랜만에 소프트웨어 개발자 여러분을 위한 포스팅을 올려봅니다. 분위기 환기도 할 겸해서 말이죠. 어제 회사에서 후배들과 패키지 설계에 대한 토론을 하다가 저희 회사에 지난 달에 입사한 후배로부터 정말 감동적인 찬사를 들었습니다. '과장님, 한달 전에 동일한 주제로 설명해주실 때보다 더 명확하고 자연스럽게 설명을 해주시네요.' 一日又一新(일일우일신) 이라... 이보다 고마운 얘기 별로 없을 것입니다.
[객체지향 프로그래밍 : Object-oriented programming]
Alan Kay의 글에 대한 해설에 들어가기 전에 말씀드리고 싶은 것은 OOP에 대한 용어 번역이 잘못되었다는 것입니다. 'oriented'라는 단어가 사전에서는 '지향'이라고 설명되어 있지만, 그 고어적인 뜻은 '비롯되다', '해가 뜨는', '출현하는', '발생하기 시작하는' 이라는 뜻을 가지고 있습니다. 따라서 'Object oriented'라는 용어는 '객체에서 비롯된다'라고 해석할 수 있지요. 저는 이것이 좀 더 정확한 해석이라고 생각합니다.
객체지향 기술로 개발되는 모든 소프트웨어는 근본적으로 객체들의 집합으로 설계되어야 한다는 사상이 이처럼 간결한 표현으로 압축되어 있습니다. 객체지향을 공부하고, 이를 자신의 근본 이념으로 내세우려는 개발자들은 OOP의 의미를 항상 되새겨야 할 것입니다. 그럴 수 있다면 객체지향 시스템의 설계 및 구현은 한결 쉬워지게 마련입니다.
대체적으로 제대로 객체지향을 이해하지 못하는 개발자(과거의 저 자신을 포함합니다.)들은 거대한 객체(혹은 클래스) 만들어 놓고 그 안에서 구조적 프로그래밍 기법을 구사합니다. 그러면서, 객체지향은 어렵다, 객체지향은 이상적인 논리다, 객체지향은 환상이다 라고 말하고는 합니다.
그런데, 왜 세계 최고의 소프트웨어 기업인 마이크로소프트는 자신들의 모든 기술에 객체지향을 접목하고 기존 비주얼 베이직 개발자들의 원성을 사면서까지 객체지향기술을 고집할까요? 왜 최고의 구루(guru)들은 너나 할 것 없이 객체지향 기술이 해답이다 라고 말할까요? 왜 공개 소프트웨어 진영의 개발언어는 대부분 객체지향을 사용할까요?
우리가 제대로 이해하지 못하는 것입니다. 대한민국 개발자들은 자동차라는 새로운 수단을 손에 넣고도 자동차를 운전할 줄 몰라, 그것을 뒤에서 밀고 가면서 레이싱하고 있는 것입니다. 이래서야 어찌 해외 개발자들이나 아키텍트들을 뛰어넘을 수 있단 말입니까?
Object-oriented programming is based in the principle of recursive design.
객체지향 프로그래밍은 재귀적(반복적) 설계 원칙의 기반 위에 놓여 있다.
1. Everything is an object.
2. Objects perform computation by making requests of each other through the passing of messages.
3. Every object has it's own memory, which consists of other objects.
4. Every object is an instance of a class. A class groups similar objects.
5. The class is the repository for behabior associated with an object.
6. Classes are organized into singly-rooted tree structure, called an inheritance hirearchy.
감탄스럽기만 합니다. 이 문구를 왜 이제서야 접하게 되었는지 한탄스러울 뿐입니다. 처음 객체지향 디자인에 대한 원서를 사서 읽었을 때, '객체지향 프로그램은 객체라고 하는 부품들이 상호 대화 하는 과정을 통해 프로그램이 수행되는 것이다'라는 적혀 있었습니다. 컴퓨터 하드웨어라는 공간 속에 둥둥 떠다니는 객체들을 상상해 보세요. 그리고 수많은 객체들이 서로 대화하는 모습을 그려 보시기 바랍니다. SF 애니메이션을 많이 보셨다면 유사한 장면들이 자주 묘사된다는 것을 아실 겁니다. 그런데, 이런 설명이나 상상은 엄밀히 말해 틀린 겁니다!
왜냐하면 객체들이 서로 대화하기 위해서는 객체들이 병렬적으로, 혹은 동시에 동작해야 하는데 현재 쓰이는 프로그래밍 언어라거나, 하드웨어 구성은 언제나 한 순간에 하나의 객체만이 동작하는 방식을 주로 사용하고 있습니다. 수만개의 객체가 동시에 동작하는 경우는 수퍼컴퓨터에서나 가능한데 그나마 이런 시스템에서의 객체들은 '클론'입니다. 즉, 똑같은 일을 처리하는 수만개의 부품들이 동일한 작업을 수행함으로써 성능을 높이는 것입니다. 그러니까, 서로 다른 기능이 동시에 동작하는 완벽히 시스템은 제가 아는 한 아직까지 인간의 뇌 밖에 없습니다.
그렇다면, 복잡하고 다양한 기능들을 프로그램 안에 넣어야 하는 개발자 입장에서 어떻게 디자인(설계)해야 할까요? '객체의 체인(chain of object)'이라는 방식을 사용하게 됩니다. (이 표현은 제가 임의로 만들어낸 표현입니다.) Alan Kay의 요약에 주석(comment)을 다는 것보다 개발하는 과정을 설명하는게 쉽게 이해될 듯 해서 소설(?)을 써봤습니다.
하나의 객체는 오직 하나의 기능을 수행합니다. 사용자가 두개의 숫자를 입력하면 그 합을 출력하는 객체지향 프로그램을 설계해야 한다면 다음과 같은 시나리오를 만들 수 있습니다.
[객체를 만들어내는 단계]
1) 모든 부품(컴포넌트 혹은 객체)을 포함하는 객체를 하나 만듭니다. 이것을 main이라고 합시다.
2) 숫자를 입력받는 컴포넌트를 만듭니다. 이것은 단순히 키보드에서 문자들을 입력받는 컴포넌트입니다. keyReader라고 합시다. keyReader는 사용자에게 입력받은 숫자를 반환하는 기능을 가집니다.
3) 입력받은 문자가 모두 숫자로만 이루어져 있는지 검사하는 컴포넌트를 만듭니다. (numericChecker라고 합시다.)
4) 두개의 숫자를 더해 그 합계를 반환하는 객체를 만듭니다. (addNumbers라고 합시다.)
5) 합계를 화면에 출력하는 객체를 만듭니다. (printNumber라고 합니다.
[객체를 조합하는 단계]
1) 먼저 main 객체를 생성하고, main을 동작 시킵니다. 보통 main() 함수를 호출하는데, 다른 말로 입구(entry point)라고 합니다. 왜 main()은 static 속성을 가질까요? 아시는 분?
2) main 객체는 keyReader 객체를 생성하고 keyReader를 실행합니다. (여기서 main은 keyReader를 소유하거나 링크한다고 이해하시면 됩니다.)
3) keyReader는 문자를 입력 받은 후, 문자가 숫자만으로 이루어져 있는지 검사하기 위해 numericChecker 객체를 생성합니다.
자~ 이제 main - keyReader - numericChecker가 순서대로 생성되었고, main이 keyReader를 그리고 다시 numericChecker를 호출하니 체인 구조를 이루었습니다. 그리고, 한번에 하나의 객체만 순차적으로 실행되기 때문에 numericChecker가 동작하는 동안 main과 keyReader는 잠시 잠들어 있게 됩니다. numericChecker가 자신의 할일을 모두 끝내면 잠들었던 keyReader가 numericCheck의 수행 결과를 받아서 나머지 작업을 수행하는 것입니다. 더 나아가 keyReader의 작업이 끝나면 main으로 돌아가고 이런 트리구조(tree architecure) 혹은 체인 구조를 순행(traverse)하는 과정이 모여 하나의 업무 혹은 프로그램이 동작하는 것입니다.
4) numericChecker는 문자열을 검사하며 숫자만으로 이루어진 경우에는 정상으로 판단한 결과를 keyReader에 알려주고 자신은 종료합니다. 반면에 잘못된 문자를 포함하고 있다면 오류를 알려주겠지요.
5) numericChecker가 반환한 결과를 검토한 keyReader는 오류가 반환되면 다시 숫자를 입력받은 후, 또 다시 numericChecker를 실행합니다. 그리고, 최종적으로 제대로된 숫자가 반환되면 main에게 자신과 numericChecker가 읽어낸 숫자를 돌려 줍니다.
6) main 객체는 keyReader 객체를 두번 실행한 후, 그 결과 얻은 두 개의 숫자를 addNumber 객체에게 넘겨 합계를 얻습니다.
7) addNumber가 실행된 결과는 다시 main 객체로 전달됩니다.
8) main 객체는 최종 합계를 printNumber 객체에게 넘겨 화면에 출력합니다.
9) 전체를 지휘하는 main 객체가 종료하면 프로그램이 끝나게 되는 것입니다.
무표정군께... 앞으로도 좋은 자료를 올려주시면 comment를 달아 보겠습니다. 더불어 Alan Kay의 PPT를 좀 공유해주실 수 있을런지요?
+
이 글 쓰느라 점심 시간을 포기했습니다. 오늘도 면식 수행! (사발면)
왜 function은 부품이 될 수 없는가? 라는 주제로 한 번 써 보겠습니다.
+
쓰고 나니, singly-rooted tree structure = chain of object 이로군요. 뭐.. 그래도 저는 제 나름의 표현 쓰는 걸 좋아합니다.. ^^
무표정군의 블로그에서 트랙백 합니다.
오랜만에 소프트웨어 개발자 여러분을 위한 포스팅을 올려봅니다. 분위기 환기도 할 겸해서 말이죠. 어제 회사에서 후배들과 패키지 설계에 대한 토론을 하다가 저희 회사에 지난 달에 입사한 후배로부터 정말 감동적인 찬사를 들었습니다. '과장님, 한달 전에 동일한 주제로 설명해주실 때보다 더 명확하고 자연스럽게 설명을 해주시네요.' 一日又一新(일일우일신) 이라... 이보다 고마운 얘기 별로 없을 것입니다.
[객체지향 프로그래밍 : Object-oriented programming]
Alan Kay의 글에 대한 해설에 들어가기 전에 말씀드리고 싶은 것은 OOP에 대한 용어 번역이 잘못되었다는 것입니다. 'oriented'라는 단어가 사전에서는 '지향'이라고 설명되어 있지만, 그 고어적인 뜻은 '비롯되다', '해가 뜨는', '출현하는', '발생하기 시작하는' 이라는 뜻을 가지고 있습니다. 따라서 'Object oriented'라는 용어는 '객체에서 비롯된다'라고 해석할 수 있지요. 저는 이것이 좀 더 정확한 해석이라고 생각합니다.
객체지향 기술로 개발되는 모든 소프트웨어는 근본적으로 객체들의 집합으로 설계되어야 한다는 사상이 이처럼 간결한 표현으로 압축되어 있습니다. 객체지향을 공부하고, 이를 자신의 근본 이념으로 내세우려는 개발자들은 OOP의 의미를 항상 되새겨야 할 것입니다. 그럴 수 있다면 객체지향 시스템의 설계 및 구현은 한결 쉬워지게 마련입니다.
대체적으로 제대로 객체지향을 이해하지 못하는 개발자(과거의 저 자신을 포함합니다.)들은 거대한 객체(혹은 클래스) 만들어 놓고 그 안에서 구조적 프로그래밍 기법을 구사합니다. 그러면서, 객체지향은 어렵다, 객체지향은 이상적인 논리다, 객체지향은 환상이다 라고 말하고는 합니다.
그런데, 왜 세계 최고의 소프트웨어 기업인 마이크로소프트는 자신들의 모든 기술에 객체지향을 접목하고 기존 비주얼 베이직 개발자들의 원성을 사면서까지 객체지향기술을 고집할까요? 왜 최고의 구루(guru)들은 너나 할 것 없이 객체지향 기술이 해답이다 라고 말할까요? 왜 공개 소프트웨어 진영의 개발언어는 대부분 객체지향을 사용할까요?
우리가 제대로 이해하지 못하는 것입니다. 대한민국 개발자들은 자동차라는 새로운 수단을 손에 넣고도 자동차를 운전할 줄 몰라, 그것을 뒤에서 밀고 가면서 레이싱하고 있는 것입니다. 이래서야 어찌 해외 개발자들이나 아키텍트들을 뛰어넘을 수 있단 말입니까?
Object-oriented programming is based in the principle of recursive design.
객체지향 프로그래밍은 재귀적(반복적) 설계 원칙의 기반 위에 놓여 있다.
1. Everything is an object.
2. Objects perform computation by making requests of each other through the passing of messages.
3. Every object has it's own memory, which consists of other objects.
4. Every object is an instance of a class. A class groups similar objects.
5. The class is the repository for behabior associated with an object.
6. Classes are organized into singly-rooted tree structure, called an inheritance hirearchy.
감탄스럽기만 합니다. 이 문구를 왜 이제서야 접하게 되었는지 한탄스러울 뿐입니다. 처음 객체지향 디자인에 대한 원서를 사서 읽었을 때, '객체지향 프로그램은 객체라고 하는 부품들이 상호 대화 하는 과정을 통해 프로그램이 수행되는 것이다'라는 적혀 있었습니다. 컴퓨터 하드웨어라는 공간 속에 둥둥 떠다니는 객체들을 상상해 보세요. 그리고 수많은 객체들이 서로 대화하는 모습을 그려 보시기 바랍니다. SF 애니메이션을 많이 보셨다면 유사한 장면들이 자주 묘사된다는 것을 아실 겁니다. 그런데, 이런 설명이나 상상은 엄밀히 말해 틀린 겁니다!
왜냐하면 객체들이 서로 대화하기 위해서는 객체들이 병렬적으로, 혹은 동시에 동작해야 하는데 현재 쓰이는 프로그래밍 언어라거나, 하드웨어 구성은 언제나 한 순간에 하나의 객체만이 동작하는 방식을 주로 사용하고 있습니다. 수만개의 객체가 동시에 동작하는 경우는 수퍼컴퓨터에서나 가능한데 그나마 이런 시스템에서의 객체들은 '클론'입니다. 즉, 똑같은 일을 처리하는 수만개의 부품들이 동일한 작업을 수행함으로써 성능을 높이는 것입니다. 그러니까, 서로 다른 기능이 동시에 동작하는 완벽히 시스템은 제가 아는 한 아직까지 인간의 뇌 밖에 없습니다.
그렇다면, 복잡하고 다양한 기능들을 프로그램 안에 넣어야 하는 개발자 입장에서 어떻게 디자인(설계)해야 할까요? '객체의 체인(chain of object)'이라는 방식을 사용하게 됩니다. (이 표현은 제가 임의로 만들어낸 표현입니다.) Alan Kay의 요약에 주석(comment)을 다는 것보다 개발하는 과정을 설명하는게 쉽게 이해될 듯 해서 소설(?)을 써봤습니다.
하나의 객체는 오직 하나의 기능을 수행합니다. 사용자가 두개의 숫자를 입력하면 그 합을 출력하는 객체지향 프로그램을 설계해야 한다면 다음과 같은 시나리오를 만들 수 있습니다.
[객체를 만들어내는 단계]
1) 모든 부품(컴포넌트 혹은 객체)을 포함하는 객체를 하나 만듭니다. 이것을 main이라고 합시다.
2) 숫자를 입력받는 컴포넌트를 만듭니다. 이것은 단순히 키보드에서 문자들을 입력받는 컴포넌트입니다. keyReader라고 합시다. keyReader는 사용자에게 입력받은 숫자를 반환하는 기능을 가집니다.
3) 입력받은 문자가 모두 숫자로만 이루어져 있는지 검사하는 컴포넌트를 만듭니다. (numericChecker라고 합시다.)
4) 두개의 숫자를 더해 그 합계를 반환하는 객체를 만듭니다. (addNumbers라고 합시다.)
5) 합계를 화면에 출력하는 객체를 만듭니다. (printNumber라고 합니다.
[객체를 조합하는 단계]
1) 먼저 main 객체를 생성하고, main을 동작 시킵니다. 보통 main() 함수를 호출하는데, 다른 말로 입구(entry point)라고 합니다. 왜 main()은 static 속성을 가질까요? 아시는 분?
2) main 객체는 keyReader 객체를 생성하고 keyReader를 실행합니다. (여기서 main은 keyReader를 소유하거나 링크한다고 이해하시면 됩니다.)
3) keyReader는 문자를 입력 받은 후, 문자가 숫자만으로 이루어져 있는지 검사하기 위해 numericChecker 객체를 생성합니다.
자~ 이제 main - keyReader - numericChecker가 순서대로 생성되었고, main이 keyReader를 그리고 다시 numericChecker를 호출하니 체인 구조를 이루었습니다. 그리고, 한번에 하나의 객체만 순차적으로 실행되기 때문에 numericChecker가 동작하는 동안 main과 keyReader는 잠시 잠들어 있게 됩니다. numericChecker가 자신의 할일을 모두 끝내면 잠들었던 keyReader가 numericCheck의 수행 결과를 받아서 나머지 작업을 수행하는 것입니다. 더 나아가 keyReader의 작업이 끝나면 main으로 돌아가고 이런 트리구조(tree architecure) 혹은 체인 구조를 순행(traverse)하는 과정이 모여 하나의 업무 혹은 프로그램이 동작하는 것입니다.
4) numericChecker는 문자열을 검사하며 숫자만으로 이루어진 경우에는 정상으로 판단한 결과를 keyReader에 알려주고 자신은 종료합니다. 반면에 잘못된 문자를 포함하고 있다면 오류를 알려주겠지요.
5) numericChecker가 반환한 결과를 검토한 keyReader는 오류가 반환되면 다시 숫자를 입력받은 후, 또 다시 numericChecker를 실행합니다. 그리고, 최종적으로 제대로된 숫자가 반환되면 main에게 자신과 numericChecker가 읽어낸 숫자를 돌려 줍니다.
6) main 객체는 keyReader 객체를 두번 실행한 후, 그 결과 얻은 두 개의 숫자를 addNumber 객체에게 넘겨 합계를 얻습니다.
7) addNumber가 실행된 결과는 다시 main 객체로 전달됩니다.
8) main 객체는 최종 합계를 printNumber 객체에게 넘겨 화면에 출력합니다.
9) 전체를 지휘하는 main 객체가 종료하면 프로그램이 끝나게 되는 것입니다.
무표정군께... 앞으로도 좋은 자료를 올려주시면 comment를 달아 보겠습니다. 더불어 Alan Kay의 PPT를 좀 공유해주실 수 있을런지요?
+
이 글 쓰느라 점심 시간을 포기했습니다. 오늘도 면식 수행! (사발면)
왜 function은 부품이 될 수 없는가? 라는 주제로 한 번 써 보겠습니다.
+
쓰고 나니, singly-rooted tree structure = chain of object 이로군요. 뭐.. 그래도 저는 제 나름의 표현 쓰는 걸 좋아합니다.. ^^
# by | 2005/09/02 12:38 | Development | 트랙백(1) | 핑백(1) | 덧글(7)





제목 : OOP 세상의 미스터리
[개발,보통] Sunny's Description of OOP 객체지향프로그래밍(이하 OOP)는 ‘잡힐 듯이 잡히지 않는 사랑’일까? 소프트웨어 개발자 K 씨는 지난 3년간 현장에서 자바를 이용해 프로젝트를 수행해 왔다. K는 클래스를 디자인 하고, 클래스의 객체를 생성하며, 메시지 패싱을 통해 프로그램을 수행하고, 필요에 따라......more
... kito가 좋은가?by 권남 Selection sort, Binary searchby coffeejava java5 Generics - Introductionby 너구라 객체지향에 대한 나름의 해설by 써니 20090622과제by 악두이퍼블리싱 및 추천같은 카테고리의 글이 글과 관련된 글 쓰기 (트랙백 보내기)TrackbackURL : http://kingo ... more
다음 것도 기대하고 있겠습니다.!
Alan kay에 대한 ppt자료가 따로 있는게 아니고 수업도중에 고거 한장만 끼어있었거든요-_-; 그래서 ppt공유는 힘들것 같습니다. 수업자료라도 필요하시다면야;;