Recommanded Free YOUTUBE Lecture: <% selectedImage[1] %>

Contents

문서정보

작성자 정보

  • 최초 작성자: mwyun([멍])
  • 이래저래 수정한 사람 : yundream

히스토리

  • 내용 대폭 수정/추가 - 2009/6/9
    1. 오탈자 수정
    2. 문맥에 맞지 않는 내용 수정/추가/삭제
  • http://jamesthornton.com/eckel/TIJ-3rd-edition4.0/TIJ3.htm <-- 이문서 어떤가요? 객체에 대한 개념설명으로 괜찮은것 같은데, 이거 정리하고 뺄거 빼고, 살좀 붙이면 스터디에 괜찮을 듯.. - yundream

객체지향

객체지향은 잘못된 번역인가 ?

객체지향은 컴퓨터 소프트웨어 공학에서 사용하는 용어로 Object-oriented을 번역한 단어다. 이것을 객체지향이라고 번역하는게 Object-oriented 라는 본래의 의미를 제대로 표현해줄 수 있느냐 아니냐를 문제삼는 경우도 있다. 우리가 일반적으로 사용해왔던 객체와 영어권에서 사용하는 Object는 집<->House처럼 명확히 의미가 일치하지 않으므로 그냥 오브젝트 오리엔트드라고 그대로 읽어야 한다는 의견도 있다.

이러한 논란이 생기는 이유는 Object라는 단어가 다분히 철학적인 의미를 포함하고 있기 때문이다. 서양 철학은 그리스 철학을 토대로 하고 있는데, 그리스 철학은 자연에서 독립적인 사물에 대한 관찰을 통한 탐구가 철학적 (과학적)사고의 방법론이였다. 르네상스시대의 철학은 이러한 그리스 철학을 계승하고 있고 지금까지 이어지고 있다. 고대 그리스에서 자연 발생설과 같은 설이 나온 것도 이러한 관찰의 결과였다. 아리스토텔레스가 관찰을 해보니, 썩은 나무에서 저절로 벌레가 생기고 시체에는 구더기가 생기더란 것이다. 이러한 관찰의 결과 자연 발생설이라는 가설을 세웠다. 물론 잘못된 설이긴 하지만 말이다. (당시 관찰 도구의 한계로 인한 잘못된 결과 도출)

반면 동양 철학은 자연을 이루는 개체들 보다는 이들을 모두 포함한 자연 그 자체를 포괄적으로 다룬다. 우주와 자연에서의 에너지의 흐름, 전체와의 조화와 균형의 원리에 이해를 주요하게 다른다. 게임에서도 이러한 차이가 나타나는 것으로 보인다.

물고기를 다룬다고 하면, 그리스 철학자들은 물고기가 가지는 다른 사물과 비교되는 특징을 탐구하는 반면 동양철학자는 물고기와 물이 어떻게 조화를 이루는지를 탐구한다.

이러한 동서양 철학의 차이는 문화의 차이를 만들었고, 지금도 영향을 미치고 있다. 실제 동서양인의 사물에 대한 인식의 차이를 보여주는 연구 실험 결과도 있다. 여러 명의 사람이 나오는 사진이 있다. 가운데 한 명은 즐거운 듯이 웃고 있고 나머지는 모두 무표정하거나 찡그린 표정을 하고 있다. 이 가운데 한명이 행복해 보입니까. 불행해 보입니까라는 질문에 동서양 사람들의 반응은 확연히 대비된다.

동양인들은 불행해 보인다는 응답이 다수인데 비해, 서양인들은 행복해 보인다는 응답이 다수였다. 동양인들은 전체를 보는 반면, 서양인은 개인에 좀더 집중한다.

이러한 문화적 차이 때문에 object와 객체는 그 의미가 일치하지 않는다. 우리가 알고 있는 객체는 다른 사물과 구분할 수 있는 객체라고 보는 시각이 강한데, 소프트웨어 공학에서의 객체는 철학적 사유 방식까지를 포함하기 때문이다.

그런 차이를 인정한다고 해도, 나는 객체지향이 잘못되었네 아니네 오브젝트 오리엔트드로 불러야 하네 말아야 하네 하는 논쟁은 필요없다고 생각하는 입장이다. 의미는 시대에 따라 달라지기 때문이다. 새로운 의미를 포함한 새로운 단어가 만들어지기도 하지만 (예컨데 지구촌과 같은), 기존에 있던 단어의 의미가 달라지거나 확장되기도 하기 때문이다.

객체지향이 거의 표준적인 용어로 사용되고 있고, (약간의 오해가 있을 수는 있지만) 대게 그 의미에 대해서도 이해하고, 혹은 이해 시킬 수 있는데 굳이 논쟁이 필요 없다는 생각이다.

컴퓨터라는 기계

최초의 근대적 기계의 개념을 담고 있는 기계의 제작은 아마도 고대 그리스시대로 올라갈듯 하다. 아리스토텔레스는 전쟁에서 사용될 수 있는 기계를 만들었으며, 실제 전차(현대적 개념의 탱크)도 설계했던 것으로 알려진다. 유대 전설에 나오는 골렘도 일종의 생각하는 기계 (컴퓨터)라고 할수 있겠다. 고대 부터 인간은 생각하는 기계를 꿈꿔왔던 것 같다.

이후에 만들어진 기계는 뭐 사실은 고만고만한 기계였는데 이들 기계는 주로 물리력을 이용해서 "물건을" 옮기는 일을 하였다. 바퀴와 기어들로 이루어져 있으며 제어하기 위해서 인간이나 동물의 물리력을 필요로 했으며 얼마나 많은 일을 할 수 있는지를 나타내는 단위로 마력을 사용했다. 마샬 맥루한이 지적했던 것처럼 기계라는 것은 인간의 신체의 기능을 외부로 확장하는 장치다. 컴퓨터가 나타나기 전까지의 기계들은 인간신체의 말단에 위치해서 주로 근육에 의해서 제어되는 신체를 확장시키는 용도로 만들어졌다. 바퀴, 지레, 망원경, 수레, 각종 공구들이 그것이다.

인간의 신체의 기능을 확장시키려는 시도는 인간의 뇌의 기능을 확장시키려는 시도로도 이루어진다. 기억하고 추론하는 기능이 그것이다. 물론 당시의 기술적인 한계 때문에 이러한 시도가 결실을 맺지는 못했다. 비교적 단순하다고 생각되는 아날로그 계산기와 그 응용정도로 만족해야 했다.

그러다가 컴퓨터(:12)라는 기존의 기계의 개념과는 매우 다른 기계가 만들어진다. 이 기계는 인간의 뇌의 기능을 확장시키려고 한다는 점에서, 기어를 통해서 작동하는 아날로그 계산기와 기본적인 목적에 있어서 같다고 할 수 있다. 그러나 기존의 계산기와 다른 근본적인 차이점을 가지고 있었다. 바로 전기와 전자를 이용해서 작동한다는 점이였다. 아날로그 장비로 인간의 뇌를 확장시키는데 있어서 어려움은 아날로그 장비의 핵심인 기어의 크기와 기어들을 이루고 있는 금속의 특징이였다. 기어는 크기가 컸으며 녹이 쓸고 잘 마모가 되었으며, 쉽게 고장이 났다. 복잡한 기계를 만들려고 한다면 수천 혹은 수만개의 기어와 태엽이 필요했다. 게다가 느리기 까지 했다. 또한 한번 만들어지면, 그 기능을 바꾸기가 쉽지 않았다. 이들 계산기는 기어와 태엽의 물리적인 배치가 소프트웨어의 역할을 했다. 즉 하드웨어만 있었지 소프트웨어는 없었다. 범용 기계를 만들기 위해서는 하드웨어와 소프트웨어를 분리할 필요가 있다.

반면 전기와 전자로 작동하는 기어와 태엽에 비해서 그 속도가 비교자체를 할 수 없을 정도로 빨랐다. 물리적인 제약에서도 비교적 자유로울 수 있었다. 또한 컴퓨터는 소프트웨어와 하드웨어를 분리할 수 있었는데, 이는 범용추론기계를 만들 수 있는 길을 열어 놓았다.

컴퓨터는 정보를 처리함에 있어서 획기적인 기계이긴 했지만 아날로그 기계와는 달리 상태가 거짓으로 표현되는 한계를 가지고 있었다. 참과,거짓으로 정보분석이 진행되는 논리연산에는 효율적이였지만 아날로그 적인 실세계의 다른 정보들을 처리하기에는 그다지 효율적이지 못하다. 초기에는 컴퓨터의 사용용도가 한정적이였으므로 ,거짓을 잘 이용하는 정도로 대부분의 일을 처리할 수 있었다. 프로그래밍언어 역시 이러하였다. 기계어, 어셈블리어, C(이론이 있을 수 있겠다) 등이 그러한 부류에 속한다.

거짓에 기초를 둔 논리연산은 어떤 일련의 순서를 따르면서 정보를 처리하도록 되어 있다. 컨테이너 벨트를 이용해서 물건을 처리하는 것으로 보면 될 것이다. 컨테이너 벨트는 물건과 물건을 처리하는 프로세스가 분리되어 있는데, 컴퓨터 역시 데이터데이터를 처리하는 방법이 분리되어 있다. 이러한 방식은 복잡하지않은 정보를 처리할때는 효율적이지만 가계/기업경영/문서작성/음악재성/공장제어/게임에서와 같이 정보와 정보가 상호연관되어서 복잡하게 얽혀있는 경우에는 효율이 극히 떨어지게 된다. 수백개의 컨테이너 벨트가 만들어져 있는데, 필요에 따라서 이들 각 컨테이너를 서로 연결시켜서 데이터를 처리해야할 경우를 생각해보면 될것이다. 입력과 출력이 매우 명확한 제조업에서야 컨테이너벨트를 재배열해야 하는 일이 그다지 필요 없겠지만 소프트웨어 개발영역은 그렇지 않다. 따라서 소프트웨어를 개발하고 유지하고 보수하는데 많은 비용이 들게 된다.

그래서 만들어진게 "객체지향 프로그래밍"으로 컴퓨터가 데이터와 데이터의 처리과정을 분리시켜서 생각하는걸 하나의 객체로 보고 처리하도록 만들어진 방법론이다. 이 방법론을 이용해서 코드의 재사용성, 유지/보수성을 높이고자 하게 된다.

객체란

간단히 말하자면 객체는 주변에서 볼 수 있는 모든 (관찰되어지는)사물이다. 삽살개, 호랑이, 세포, 사람.. 전부다 객체다. 또한 눈에 보이는 구체적인 것 뿐만 아니라 경제, 국가, 시장 같은 눈에 보이지 않는 것도 객체라고 한다. 모든 것이 객체다!!! 단순명료하긴 하지만 너무 포괄적인 것 같으니 객체의 특징에 대해서 정리해볼 필요가 있을 것 같다.

객체는 내면과 내면을 감싸는 외피를 가진다. 세포라는 객체는 세포내용물질과 이들을 감싸는 외피로 구성이 된다. 관찰자에게 보이는 것은 외피가 된다. 내용물들과 내용물들이 상호작용하는 과정은 관찰자에게 감추어진다. 이렇게 내면을 감추는 외피를 가지는 것을 추상이라고 하는데, 이 추상은 객체가 가지는 대표적인 특징이다. 여기에 따르면 외피를 가지지 않는 것은 객체라고 할 수가 없다. 외피가 중요한 이유는 주변의 다른 사물과 구분되는 표면이 있어야 관찰자에게 독립적인 사물로 보여질 수 있기 때문이다. 표면은 경계라고 해도 좋을 것이다.

경제나 국가와 같은 것들도 인간은 객체라고 본다. 물리적인 외피를 가지지 않지만 인간의 인식하에서 경제는 경계를 가지고 있기 때문이다. 경계를 가지고 있으므로 관찰자인 인간은 경제를 관찰하고 분석할 수 있다. 여기에서 어떤 대상이 객체로 보이느냐 아니냐 하는 것은 상대적일 수 있음을 알 수 있다. 경제관념이 없는 지역의 사람들에게는 경제는 관찰할 수 있는 대상이 아니기 때문이다.

객체는 객체를 포함할 수 있다. 치아와셰퍼드는 객체다. 여기에서 더 나아가 이들 치아와나 셰퍼드를 통칭하는 도 객체가 될 수 있다. 는 치아와와 셰퍼드와 같은 객체의 공통적인 특징을 분석해서 인간의 지성이 만들어낸 가상의 개념이지만 고양이라는 다른 개념과 구분되는 외피를 가지고 있으므로 객체라고 할 수 있다. 라는 객체는 치아와, 셰퍼드 객체를 포함한다. 이러한 객체의 속성을 이용하면 객체의 계층적- Hierarchy - 구조를 만들 수 있다. 이것은 복잡한 자연현상을 단순화 시켜서 인식할 수 있도록 도와준다. 대표적인 예가 종,속,과,목,강,문,계일 것이다.

객체는 주변환경 혹은 다른 객체와 상호작용한다. 생물의 경우 상호작용은 감각기관을 통해서 내부로 정보를 받아들인 다음 이를 처리하고 운동기관을 통해서 다른 객체를 조작한는 형식으로 이루어진다. 개가 위협적으로 달려들면 눈으로 이 정보를 받아들여서 처리한다음 다리근육을 움직여서 달아나거나 혹은 온몸을 이용해서 싸우거나 하는 식이다. 이러한 상호작용은 경제와 같은 구체적인 형태를 가지지 않은 객체에도 적용된다. 경제의 경우에는 신문,뉴스, 주식매입,은행업무등을 통해서 상호작용할 것이다.

이상에서 객체의 다음과 같은 특징을 뽑아낼 수 있을 것 이다.
  1. 객체는 내면과 내면을 감싸는 외피를 가진다.
  2. 내면은 외피 내부로 숨겨지며 이를 추상이라고 한다.
  3. 객체는 외피를 가짐으로써 주변사물과 독립적으로 구분될 수 있다.
  4. 객체는 외피를 가짐으로써 관찰대상이 될 수 있다.
  5. 구체적인 형태를 가지지 않는 것들 - 경제, 국가 - 도 객체가 될 수 있다.
  6. 객체에 대한 정의는 상대적이다.
  7. 객체는 객체를 포함할 수 있다.
위의 객체에 대한 내용은 다분히 철학적, 다른말로 말장난으로 보일 수 있을 것 같다. 그러나 이러한 특징은 컴퓨터 영역에서의 Object-orinted Programming 에도 그대로 나타난다.

객체와 class

아리스토텔레스가 추상적인 분류체계를 구축할 수 있었던데에는 동물에 대한 다양성과 그 기능에 대해서 특히 관심이 많았기 때문이다. 이들을 관찰하기 위해서는 그 다양함안에서도 공통되는 속성이나 행동약식 등을 찾아서 체계적으로 분류할 필요가 있었기 때문이다. 이러한 고찰의 결과는 “the class of fishes and the class of birds”이라는 그의 생각에 요약되어서 나타난다.

여기에서 fishes는 class다. 농어,빙어,붕어와 같은 객체들로 부터 공통의 속성을 뽑아내어서 만들어놓은 추상객체다. 이렇게 fishes라는 클래스를 만들어 놓으면, 이제 새로운 생물이 발견되더라도 fishes라고 부를 것인지 말것인지를 쉽게 결정할 수 있다. 새로 발견된 생물이 fishes라는 클래스가 가지고 있는 속성과 행동양식에 맞는지를 검토하면 되기 때문이다.

즉 class는 객체의 공통적인 속성과 행동양식- 메서드 -을 정의해 놓은 추상객체로 정의 내릴 수 있다.

class는 상위의 class를 가질 수 있다. 개 < 포유류 < 생물 이런 식이다. class는 객체가 될 수 있고, 객체가 클래스가 될 수 있다. 일반적으로는 속성과 행동양식이 실체된 경우를 객체라고 하고 그렇지 않고 속성과 행동양식을 단지 정의만 하고 있는 추상객체class라고 한다. 구체적인 실체를 가지지 않는 는 class 이고, 의 속성과 행동양식을 가진 실체하는 치아와,삽살개를 객체로 보는 식이다.

분류체계로 볼때 객체는 class에 하위분류가 된다.class의 속성과 행도양식을 상속받아야 하기 때문이다. 때문에 치아와는 개다라는 명제는 성립하지만 개는 치아와다라는 역은 성립하지 않는다.

Interface

객체는 내면이 외피에 의해서 감추어진다고 했다. 환경과 상호작용하기 위해서는 환경이 내면으로 전달되어야 한다. 이때 문제가 되는 것은 외피에 의해서 내면과 환경이 단절되어 있다는 점이다. Interface는 환경의 변화를 내면으로 전달하는 역할을 하는 장치다. 인간을 예로 들자면, , , , 등이 Interface로 이것을 이용해서 외부환경과 상호작용하게 된다. 가시광선을 눈으로 받아들여서 시신경을 통해서 내면에 있는 뇌로 전달해서 해석하고, 해석된 결과에 따라서 반응하는 식이다.

자동차의 Interface 는 핸들,브레이크,악셀레이터등이 될 것이다.

객체 지향과 과학

모든 사물을 객체로 바라보는 주의는 실증주의경험주의에 바탕한 현대적인 과학의 바탕이 된다. 즉 인간의 오감과 상호작용해서 분석되어진 정보를 오랜시간 분석해서 - 즉 경험을 통하여 - 보편적인 지식으로 만드는 과학적사고 방식 만들어냈다.

따라서 좋은 객체지향 프로그램을 만들려면, 관찰에 따른 실증주의와 경험주의적 사고방식이 중요하다. 이러한 사고방식은 분석력을 필요로 하는 경우가 많다. 현대 교육과정이 분석력을 특히 중요시하는 이유가 근대 서양의 자연 과학 철학을 기반으로 하고 있기 때문이다.

그렇다고, 과학적 사고방식이 항상 좋은 것이라고 생각할 필요는 없다. 이런 생각은 서양 철학이 동양 철학에 비해서 우월하다라는 식의 사고 방식이며, 편견이 될 수 있다. 20세기 후반 부터 동양 철학이 재 조명을 받는 것만 봐도 알 수 있다.

마찬가지로 객체지향을 신성시할 필요도 없다. 어떤 이론이나 방법론도 신성시, 절대적이라는 수식어가 붙는 순간 부작용을 피할 수 없게 된다.

과학과 종교

과학적 사고는 상호작용 가능한 객체를 대상으로 이루어진다. 이런 의미에서 종교는 과학과 다른 길을 가게 된다. 신과 상호작용할 수는 없는 노릇이기 때문이다. 상호작용할 수 없는 건 객체가 아니다. 언젠가 신과 제대로 상호작용할 수 있는 어떠한 방법을 찾아낸다면 종교도 과학이 될 수는 있겠지만 말이다. 아 물론 지금도 신도들은 기도를 통해서 신과 상호작용 한다고 하지만 상호작용의 결과를 보여주지 않으니, 분석불가가 된다. 입력은 있는데 출력은 없는 상태라고나 할까.

신을 직접 입증하는게 불가능하다고 생각이 되자, 그들의 성서에 적혀있는 신화적 내용이 신화가 아닌 사실임을 증명하는 것으로 신이 있음을 간접적으로 증명하고자 하는 시도가 있었다. 신화는 어떤 부족의 역사를 담고 있는 경우가 많고, 역사는 과학적 탐구가 가능한 영역이니 말이다. 이것을 창조과학이라고 한다.

그러나 창조과학이 의미가 있을지에 대해서는 회의적이다. 설사 역사적 사실이 입증되더라도 말이다. 신화속의 도시로만 알려졌던 트로이가 발견이 되고, 아킬레우스가 실제 존재하던 인물이였음이 증명되었다고 해서, 아킬레우스가 신의 아들이고 트로이 전쟁을 신들이 배후조정했다는 증거가 되는건 전혀 아니기 때문이다. 종교는 그냥 믿음의 영역으로 두면 되는 것이다.

때때로 기술이 발전함에 따라서 너무터무니 없어서 신화와 같은 것으로 생각되던게 상호작용 가능한 과학적 탐구가능한 객체가 되기도 한다. 4차원이네 10차원이네 하는 것들은 과거에는 터무니 없는 것이였으나 입자가속기의 등장으로 그 실체를 거의 규명할 수 있게 된게 그 예가 될 것이다. 그렇다고 해서 신과 대화가능한 기계를 만들어 낼 수 있을까 ?? 뭐, 이벤트호라이즌호는 강력한 중력발생기를 이용해서 뜬금없는 지옥도 다녀오긴 했지만 이건 어디까지나 영화의 이야기고.

추상(抽象)화 와 추상화 과정

위에서 객체는 내부를 숨기는 외피를 가진다고 했다. 이것을 추상이라고 하는데, 객체의 가장 큰 특징중 하나다. 이 추상에 대해서 알아보도록 하자.

현대적인 추상개념을 체계화 한것은 플라톤으로 생각된다. 플라톤은 이데아라는 것을 주창하였다. 세상은 이데아라는 완전한 세계에 있는 원본틀의 그림자로 생겨난 것이다라는게 이데아의 핵심이다. 원본의 그림자이니 세상은 언제나 불완전할 수 밖에 없다. 이데아는 완전한세계, 영혼으로 볼 수 있는 세계라는게 플라톤의 생각이었다.

를 예로 들어보자. 를 본적이 있는가 ? 뜬금없는 말 같지만 그 자체를 본적은 없을 것이다. 왜냐하면 는 물리적인 대상을 가리키는게 아니기 때문이다. 우리는 삽살개, 치아와, 셰퍼드를 볼 수 있지만 를 본적은 없다. 플라톤이 주장하는 바에 따르면 가 바로 치아와 삽살개 셰퍼드등 이 세계에 존재하는 여러가지 개의 성질을 가지는 것들의 유일한 원본이다. 이 유일한 의 그림자가 바로 우리가 볼수 있는 치아와 인 것이다. 이데아는 우리가 사는 세계보다 차원이 높은 세계이므로 우리는 단지 의 그림자만을 볼 수 있을 뿐이다.

이처럼 차원이 낮아지면 얻을 수 있는 장점이 있다. 그것은 수많은 개의 성질을 가지는 객체를 만들어 낼 수 있다는 점이다. 앞서 이 세상에 물리적으로 존재하는 개들은 이데아 의 그림자라고 했는데, 그림자는 그 모습이 완벽하지 못하다. 광원의 거리와 흔들림에 따라서 찌그러지기도 하고 커지거나 작아지거나 할 수 있다. 는 하나이지만 수많은 개들이 존재하는 이유이다.

플라톤이 이데아를 생각해 냈던 것을 반대로 하면 그게 추상화가 된다. 즉 멍멍 소리를 내고, 꼬리를 흔들며, 다리가 4개고, 코가 뾰족한 특징을 가지는동물들을 라고 정의 하는 것이다. 이렇게 해서 우리는 눈에 보이지 않는 라는 새로운 상위 차원의 개념을 만들어내게 되었다.

추상화 과정이란 어떤 구체적인 사물로 부터 공통적인 속성을 찾아내어서 그것들을 포괄할 수 있는 상위의 포괄적 개념을 만들어내는 과정이다.

컴퓨터에서의 추상화

컴퓨터 언어역시 이러한 추상화 과정을 거친다. 가장 간단한 어셈블리는 이를테면 생명체의 바이러스라고 할만한데, 가장 간단한 추상화 과정을 거친다. 기계어와 거의 일대일 대응을 하는데, 다만 좀더 이해하기 쉽게 만들도록 "한단계"의 추상화 과정을 거쳤을 뿐이다. 포트란, 베이직, C(:12)와 같은 언어들은 어셈블리어(:12)에 비해서 더욱 많은 추상화를 이루고 있으며, 여러가지 면에서 크게 발전되었다.

그러나 이들 언어는 컴퓨터 기계가 만들어 졌던때의 그철학을 그대로 따르고 있어서 실제 생활에서 발생할 수 있는 다양한 문제를 푸는데 있어서 절차지향적인 방법을 따른다. 이건 어셈블리어 뿐만아니라, 포트란, 베이직, C 모두에 포함된다. 절차지향적이란 컨테이너 벨트라고 생각하면 된다. 재료를 집어 넣고 컨테이너 벨트에 집어 넣으면 최종적으로 물건이 튀어 나오는 것이다. 풀어야할 문제가 복잡해 질 수록 이런 절차지향적 방법으로는 한계에 부딪히게 된다. 즉 개발모델이 문제다. 여기에서 한계란.. 문제를 풀 수 없다라는 것이 아니고, 효율적으로 풀수 없으며 단지 푸는 것 뿐만 아니라, 유지하고 보수하고 확장시키는데 기존 방법으로는 많은 시간과 비용이 소비될 확률이 많다는 것이다.

그래서 만들어진 개발 모델이 객체지향 모델이다. 컨테이너 벨트 모형을 따르는 절차지향 개발 모델에서는 데이터와 데이터를 가공하기 위한 메서드(함수)가 서로 분리 되어 있다. 데이터가 계속 흘러가고 중간에 함수가 있어서 가공하고 다시 다음 함수로 넘겨주는 방식이다.

반면 객체지향 개발 모델에서는 데이터와 메서드를 분리하지 않고 하나의 공간에 둔다.

객체지향을 목표로 제작된 최초의 (성공적인) 언어로 Smalltalk라는 언어가 있다. Java도 이 언어를 기초래 해서 만들어 졌는데, 객체지향을 위한 기본적인 노선이 정립된 언어다. 객제지향 언어라고 한다면 보통 아래의 5가지의 요소를 만족시키는 특성을 지원할 수 있어야 한다.

  1. 모든 것은 객체다 : 간단하게 생각해서 객체는 데이터와 데이터를 처리하기 위한 메서드를 함께 가지는 모든 것을 말한다. 이론적으로 객체를 이용하면 모든 사물을 완벽하게 구현할 수 있다. (자동차, 개, 건물, 은행 서비스 ..)
  2. 프로그램은 객체사이의 메시지 전달을 이용해서 통신한다 : 두명의 사람(객체)가 상호작용하기 위해서 대화를 하는 것과 마찬가지다. 프로그램의 경우 두개의 객체(보통 클래스, 패키지라고 한다)를 연결하기 위한 메시지 전달 클래스를 만들 수도 있을 것이다. 사람과 사람이 대화를 하는데 중간에 매질(공기)이라는 객체가 대화를 전송하는 것과 같은 이치다.
  3. 각각의 객체는 자신만의 메모리를 가진다 : 객체는 데이터와 메서드를 하나의 공간에서 다루며, 객체는 다른 객체와 독립적으로 행동한다. 고로 자신만의 데이터를 저장하기 위한 공간을 가질 수 있어야 한다.
  4. 모든 객체는 이름을 가진다 : 각 객체는 독립적으로 구분될 수 있어야 한다. 그러기 위해서 이름(type)을 부여한다. 각각의 사람을 구별하기 위해서 "이름"을 부여하는 것과 마찬가지다.
  5. 동일한 특성의 객체는 동일한 메시지를 사용한다 : A라는 사람과 B라는 사람은 독립적인 객체이지만, 또한 "사람"이라는 동일한 특성의 객체이기도 하다. 이들 객체간의 대화를 위해서는 당연하지만 같은 언어가 사용되어야 할 것이다. 사람과 개의 경우에는 대화가 되지 않을 것이다. 프로그램에서도 동일한 특성의 객체들은 동일한 메시지를 이용해야 한다.

추상화를 통해 얻는 이득

자동차를 생각해보자. 자동차는 인류가 개발한 육상이동 수단중 가장 고도로 추상화된 기계다. 자체에 발전,공급,저장,통신,제어 시설을 갖춘 소형 공장이라고 할만하다.

그러나 운전자가 이러한 모든내용을 알아야지만 자동차를 이용할 수 있는 건 아니다. 대부분의 기능들은 추상화(숨겨져)있으며, 사용자는 단지 핸들과, 브레이크, 악셀레이터와 몇개의 계기판을 볼수 있으면 운전이 가능하다.

복잡한 내부 구현을 숨김으로써 사용자는 이것 저것 신경쓸 필요 없이, 제공되는 몇개의 인터페이스만으로 사용이 가능하다. 이게 추상화가 가져다 주는 첫번째 이득이다. 자동차가 처음 나왔던게 19세기 말이였던 것 같다. 그러나 성능상의 차이는 있겠지만 100년이 지난 지금도 자동차의 기본적인 운전방법은 거의 변함이 없다. 그때나 지금이나 여전히 운전자는 핸들, 브레이크, 악셀레이터 이 3가지를 이용해서 자동차를 제어한다. 이러한것 자동차의 구현을 "추상화"함으로 가능하다.

즉 구현과 인터페이스를 분리시켜줌으로 (최초에 인터페이스만 잘 설계한다면)기능이 대폭업그레이드 되더라도 사용자는 이것에 신경쓸필요 없이 기존의 운전기술을 그대로 사용할 수 있게 된다.

프로그램개발에 있어서도 이러한 이득을 그대로 이용할 수 있다. 추상화를(잘) 시키게 되면 인터페이스와 구현을 구분시켜 줌으로써 일반 프로그램개발을 할적에 세부저인 복잡한 구조를 신경쓸 필요 없이 제공되는 몇개의 인터페이스만을 이용해서 필요한 일을 할 수 있다. 구현을 업그레이드 시켜야할 경우에도 개발자는 여기에 대해서 신경쓸 필요가 없게 된다.

간단하게 생각하자면 우리가 프로그래밍을 위해서 사용하는 open(2), write(2)같은 함수역시 추상화의 결과물이다. 우리는 open(2)의 내부구조가 어떻게 되어있는지 신경쓰지 않고도 잘 쓸 수 있다.

객체는 인터페이스를 가진다.

객체에 대해서 깊은 사고를 한 최초의 철학자는 (보통)아리스토 텔레스로 알려져 있다.그는 "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은 그 자체가 하나의 학습분야이므로 여기에서는 자세히 다루지 않을 것이다. 이런것이 있다는 정도만 이해하고 넘어가도록 하자.

객체는 서비스를 제공한다.

뻔한 얘기다. 은행업무-1객체는 고객에게 은행서비스를 제공하기 위해서, It객체는 밝게 비춰주는 서비스를 제공하기 위해서 존재한다.

OOP (Object-Oriented Programming) 개론

이 글은 제가 오래전 잡지에서 본 강좌를 타이핑하여 파일로 저장해둔 것을 올린 것입니다.

아쉽게도 잡지명이나 저자 이름은 오래된지라 기억이 나지 않지만 전문을 올렸으니 잘 읽어보시기 바랍니다.

Object-Oriented Programming의 등장

소프트웨어 위기 (Software Crisis)

컴퓨터가 출현하고 그 기능이 발달함에 따라 우리들은 그것을 사용하여 보다 편리하고 윤택한 생활 - 정말 윤택하게 되었는지 아닌지에 대한 언급은 하지 않도록 하겠다 - 을 하게 되었다. 그에 따라 소프트웨어의 수요가 기하급수적으로 증가하게된다. 결국 공급이 수요를 따라가지 못하는 상태에 이르게 된다. 하드웨어의 발전은 눈부시도록 놀라운데 그에 비하면 소프트웨어의 발전은 그 발치에도 미치지 못하고 있는 것이다. 이러한 위기상황 속에서 이를 극복하고자 하는 노력을 구체적인 방법론으로 표현한 것이 소프트웨어 공학 (SE : Software Engineering)인데, Object-Oriented Programming(Paradigm)도 바로 이 SE의 한 범주에 속한다고 할 수 있겠다. 집채만한 공룡이 메추리알 크기의 뇌를 가지고 있는 상태라고 볼 수 있을 것이다.?

소프트웨어의 구성 방법의 변천

초창기에는 모든 소프트웨어를 단지 하나의 Procedure로 만들어 냈다. 그러나 많은 시간과 여러 사람의 노력이 필요한 큰 시스템을 구축하려고 할 때에 이런 방법은 적절하지 못하다. 그래서 큰 프로그램을 각 기능별로 여러개의 Subroutine으로 나누어(Functional Decomposition) 독립적인 부분으로 만들어(Modularization) 여러사람에게 할당하고, 각각의 모듈이 완성된 후에는 그것들을 서로 짜맞추어 하나의 시스템으로 완성하는 방법을 사용하게 된다. 이것을 Modular Programming이라고 한다. 이 Modular Programming과 함께 몇몇 규칙들을 적용하여 Structured Paradigm이라는 소프트웨어 구성방법이 생겨나게 되었으며, 지금까지도 널리 사용되고 있다.

Structured 방법의 문제점

기존의 Structured 방법은 처리(Process)를 중심으로 하고 있다. 바로 이점이 문제가 된다. 데이타(Data)는 단지 강의실에서의 칠판처럼 필요할때마다 썼다 지웠다하는 보조 수단으로 여겨 그다지 중요시하지 않게 생각했다. 데이터를 독립된 단위로 보는 이러한 시각은 처리해야할 데이터의 절대적인 양자체가 적었을때는 크게 문제가 되지 않겠지만, 요즘처럼 다루어야 하는 데이터의 기본단위가 기가가 되는 경우에는 문제가 된다. 많은 데이타를 공유해야만하고, 원하는 데이타를 여기저기 마구 불러 사용하는 상황은 Modular Programming의 원리를 어기게 되었고 따라서 모듈의 재활용성(Reusablity)이 떨어지게 된 것이다. DBMS(DataBase Management System)를 사용하여 이런 문제를 다소 해결할 수는 있으나 이로서는 충분하지 않다.

Object-Oriented Paradigm의 등장

프로그램의 재활용성을 높이기 위해서는 Modular Programming, 이를 위해서는 Procedure뿐만이 아니라 데이타도 모듈화 되어야 한다는 방법론이 등장했으며 이것이 Object-Oriented Paradigm의 중요한 기본 요소가 되었다. 1960년대에 등장한 Simula(:12)는 현실세계를 Simulation하는 것을 주목적으로 하는 프로그래밍 언어였는데, 이 프로그램에 도입된 프로그래밍 개념이 바로 Object-Oriented Paradigm의 효시가 되었다.

OOP의 기본개념

Object

Object는 데이타와 이와 관련된 Procedure를 한데 묶어 표현한 소프트웨어 패키지이다. 이는현실세계가 처리중심이 아닌 사물(객체 : Object)중심으로 이루어졌다는데에 바탕을 둔 것이다. 세포(Cell)를 예로 들어 생각해 보자. 세포는 핵, 미토콘드리아, 세포질, 세포막 등으로 이루어 졌는데, 이러한 세포의 구성 요소들에게는 각각의 역활이 주어져 있다. 그러나 기관의 입장에서 살펴면, 세포의 구성 요소들이 어떠한 일들을 하는지는 그다지 중요한 사실이 아니다. 단지 단백질이나 무기질을 세포내로 전달해 주면, 세포는 그것들을 가지고 자신의 임무만을 수행하면 되는 것이다. 세포내에 어떠한 구성원들이 있는지는 알 필요도 없고, 단지 세포 그 자체로서만 인식되면 충분한 것이다. Object도 이와 마찬가지로 생각하면 쉽게 이해가 갈 것이다.

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"이라는 관점도 있다. 가장 간단한 형태의 데이터 추상은 구조체일 것이다.

Encapsulation

Data Abstraction를 이용하면 Encapsulation을 달성할 수 있다. 필요한 데이타와 Procedure를 모아 캡슐에 담는 것에 착안하여이렇게 이름을 붙인 것이다. 실제로 이 Encapsulation으로 인해 생겨난 결과가 Object이다. 예를 들면, Nucleus(핵), Mitochondria(미토콘드리아), Membrane(세포막)등의 변수들과 그와 관계된 함수들을 Cell(세포)이란 object내에 정의해 놓은 것이다. 이렇게 함으로써 우리들은 자세한 부분까지 신경을 쓸 필요가 없고 단지 세포라는 Object와 Object로의 입출력 데이터만 생각하면 된다.

Infomation Hiding

Encapsulation으로 인해 내부의 데이타는 외부로 부터 고립되었다. 데이타는 필요한 때에 단지 외부로부터의 Message에 의해서만 접근되어질 수 있는데, 이러한 것을 Information Hiding(정보 은닉)이라 한다. 만약 Object내의일부분을 수정하였다고 해도 그 변화는 단지 Object내에서만 영향을 끼치고, 이로 인하여 완전히 모듈화가 이루어지는 것이다.

Composite Object

한 Object가 다른 Object를 포함할 수 있는데 이를 Composite Object라 한다. 이렇게 함으로써 포함된 Object를 새로운 Object의 한 부분으로 단순화시킬 수 있고, 그에 대한 자세한 내용을 알 필요도 없으며 많은 주의를 기울일 필요도 없이 사용할 수 있다. 미토콘드리아와 세포와의 관계를 생각하면 될 것이다.

Message

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를 통해서만 접근될 수 있다.

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인 직사각형을 그 것이다.

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화가 가능해진다.

Polymorphism

공통된 Interface를 사용하여 하나이상의 기능을 수행할 수 있는 것을 Polymorphism이라고 한다. 이것은 Overloading과 Overriding(특별한 형태의 Overlading)을 보다 일반적으로 일컫는 표현이다.

Class

Class는 Method와 Attribute(속성)들을 포함하는 특정한 형태의 Object를 정의하는 틀(Template)이다. 따라서 Class는 금형과 같이 수많은 복제품을 만들어 낼수 있으며, 이 복제품을 Instance라고 한다. Instance는 단지 (Value)들 만을 포함하고 있으며, 따라서 이 Instance에 Method가 수신되면 Class에서 Method를 찾아 수행한다. 그러므로 'Object'는 Class의 Instance라 고 할 수 있다. 세포로 얘기하자면 어떠한 세포로도 분화 가능한 만능세포가 Class 쯤에 해당한다고 볼 수 있다. 만능세포는 자신이 위치하는 기관에 따라서 신경세포, 근육세포, 뉴런세포등 다양한 세포를 만들어 낸다.

SuperClass와 SubClass

한 Class가 다른 Class의 특정한 형태의 하나로 정의될 때 기존의 Class를 SuperClass, 새로운 Class를 SubClass라 한다.

attachment:oop-1.jpg

Inheritence(상속)

SubClass는 SuperClass의 모든 것들을 상속 받을 수 있다. 즉, SuperClass의 모든 Method와 Attribute들을 별도의 정의없이 사용할 수 있다.

Class Hierarchy

Class Hierarchy란 Class들의 Tree모양의 구조를 말한다. 이것은 -이론적으로- 제한없이 중첩(Nesting)될 수 있으며, Inheritance는 축적되어 아래 단계로 내려간다. 즉, 한 Class에서는 그 상위 Level에 있는 조상 Class의 모든 성질을 계승받을 수 있다. 이 Class Hierarchy는 정보와 정보를 다루기 위한 방법들을 전승할 수 있다는 장점을 가진다.

attachment:oop-2.jpg

예외(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이라 한다.

Virtual Class(Abstract Class)

단지 구조적인 목적으로만 사용되기 위하여 설계된 Class를 말한다. 앞으로 사용될 기능들(Attribute, Method)을 모아놓기만 하고 구체적인 구현은 나중으로 미루어, 다른 Class들의 Base Class로만 사용된다. 따라서 Virtual Class의 Instance는 존재할 수가 없다. Abstract Class라고도 하지만, Abstract Data Type과의 혼동을 방지하기 하여 일반적으로 Virtual Class라고 한다.

Multiple Inheritance(다중 상속)

한 Class가 여러개의 SuperClass를 가질 수 있도록 하는 것을 말한다. '철강회사의 노동조합장'의 경우를 예로 들어보자, 그는 유능한 용접공이며 또한 회사의 업무를 관장하는 간부이기 하다. 단지 Single Inheritanc만이 가능하다고 하면

attachment:oop-3.jpg

그림에서처럼 간부의 역활을 이중으로 정의해야 하므로 비효율적이다. 이때 Multiple Inheritance를 이용하면 효율적이다. 하지만 이때에 주의해야 할 사항이 있다. 같은 이름으로 정의된 Method가 각각의 SuperClass(용접공, 조합장)에 존재하면, 이때에는 어떤 SuperClass의 Method를 사용해야 할지 결정할 수가 없다. 즉, Conflict가 일어나게 되는 것이다.

Multiple Inheritance를 이용하면 이러한 문제를 해결할 수 있다. 그러나 함부러 마구 갖다붙이지 않도록 주의를 기울여야 한다. 중요하지 않은 곳에 오용되는 경우가 종종 있다. 위의 예에서 '조합장'의 경우를 생각해 보자. Multiple Inheritance를 올바르게 사용한 것인가? 이전에는 용접공이었지만 조합장이 된 후에는 실제로 용접을 하지않고 회사의 업무만을 관리하게 되었다면 그때부터는 사실상 용접공이라고 할 수가 없다. 이러한 경우에는 용접공의 계승을 없애버려야 한다. 계승되는 SuperClass의 성질을 온전히 포함하고 있는지 살펴보는 것이 올바르게 Multiple Inheritance를 사용하고 있는지 여부의 판단 기준이 된다.

Class Hierarchy의 구성

제대로 된 Class Hierarchy를 구성하기 위해서는, 우선 나중에 쉽게 재활용될수 있도록 일반적인 목적으로 설계되어야 한다. 또한 이 Class Hierarchy는 현실세계를 잘 반영할 수 있어야 하며, Method는 가능한한 가장 높은 최상의 단계에서 정의되어야 중복을 줄일 수 있다.

attachment:oop-1.jpg

Object-Oriented 방법을 이용한 Software의 구축

Reusability(재활용성)

Object-Oriented 방법의 가장 중요한 착안 사항이 바로 이 재활용성일 것이다. Reusable Module이 많이 마련되어 있다면 그것들을 이용하여 Software를 구축하면 보다 적은 노력만이 필요할 것이다. 실제로 Reusable Module을 설계하는 데에는 설계, 분석의 과정을 거쳐야 하므로 설계상의 자세한 내용은 줄이고 개념적인 것만 살펴보자.

Reusable Module을 설계하는 것은 대게의 경우 필요한 것을 그때 그때 만들어 쓰는 것보다 더 많은 계획과 노력을 필요로 한다.

OOP의 핵심은 추상화에 있는데, 이 추상이라는 것은 다루고자하는 객체들의 공통된 속성을 뽑아내어서 일반화된 계층을 만들어 내는 행위다. 그러므로 다루어야 할 객체들과 주변환경에 대한 폭넓은 이해가 우선적으로 필요하다. 삽살개, 진돗개, 치아와 등에 대한 공통적인 특징들을 제대로 알고 있어야 비로서 를 제대로 정의할 수 있는 것과 마찬가지다. 많은 시간이 필요할 수 밖에 없다.

이들 Reusable Module은 Class 를 중심으로 설계된다. 전에 언급한 Class의 장점들 - 현실세계를 잘 반영할 수 있으므로 인간의 생각을 표현하는데에 수월하고, 상속(Inheritance)을 이용하여 확장이 쉬워지며, Polymophism을 적용하여 특별한 예외 경우를 잘 처리할 수 있는 점 등 - 이 Module을 설계하는데 꼭 맞게 적용되기 때문이다. Reusable Class는 필요한 것들을 직접 설계해서 얻을 수 있을 뿐만 아니라, Programming Language에서 제공되기도 하고, 때로는 상점에서 구입하는 것이 효율적일 때도 있다.

Object를 직접 사용한 Software의 구축

기존에 만들어진 Reusable Object를 모아 Software를 구축할 수 있다 하지만 이 방법은 필요로 하는 Object들을 모아 실제로 구동시키는 새로운 Object를 만들어야 하는데 불편함이 있다 (Program = Class Libraries + Solution Classes). 물론 기존의 방법에 비하면 이 정도로도 훌륭하지만, 더 나은 방법이 있다.

Simulation

그 방법은 Class Library들을 모아 Modeling을 하는 것이다. 즉, 기존의 Class들을 이용하는 High-Level Object 까지도 미래의 필요에 대비하여 설계하는 것이다. 은행의 전산처리 System을 구축하는 것을 예로 들어보자. 여기에는 입출금 계산, 신용카드 결재, 각종 공과금 자동납부 등 여러가지 작업들이 필요할 것이다. 이때에 Class Library들을 이용하여 입출금 계산 System, 신용카드 결재 System, 공과금 자동납부 System 등을 미리 설계해 놓으면, 나중에는 단지 이것들을 끼워 맞추기만 하면 되므로 Class Library들을 직접 이용하여 모든 것을 다시 설계하는 것보다 훨씬 수월할 것이다. 신용카드 결재 방법을 바꾸었다고 하자. 그러면 단지 신용카드 결재 System, 그 중에서도 특정한 Class들만을 고치면되므로 수정도 용이하게 할 수 있다.

Rapid Prototyping

Prototype이란 한마디로 '시험판(Trial Version)'이라고 할 수 있다. 실제로 기업에서의 간부들은 '그들이 정말로 원하는 것이 무엇인지'를 제대로 알지 못하고 있는 경우가 대부분이다. 그들에게는 프로그램이 동작하는지 아닌지만 중요할 뿐이다. 자신이 만들 프로그램이 어떻게 돌아갈지를 미리 확인하는 차원에서 필요하기도 하지만 윗분들의 정서적안정을 위해서 만들필요가 생기기도 한다.

System의 구축

Reusable Class들의 Library를 구축한다. 이 Class들을 이용하여 Working Model을 구축한다. Rapid Prototyping을 이용하여 System을 구축한다. - 필요에 따라서는 이전의 단계로 되돌아갈 수 있다(Feedback).

Object-Oriented 방법의 장점과 단점

http://blog.crisp.se/henrikkniberg/images/old-tool-was-better.jpg

그림출처:crisp

OOP면 모든게 해결될 거라고 생각하는 개발자들이 있다. 최신이 언제나 좋은 건 아니다. 자기가 잘 할 수 있는 방식으로 하는게 최고다. 자고로 프로그램이란건 돌아가야 하는하고 기본적으로 자신을 위해서 만드는 것이기 때문이다.

장점

우선 짚고 넘어가야 할 점은, 기존의 사고 방식을 가지고 단순히 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(:12) 뿐만 아니라 그에 해당하는 여러가지 Tool 들, Graphics가 지원되는 Hardware System 들이 OOP를 필요로 한다. 그러므로 기존의 패러다임을 OOP로 바꾸는 작업이 필요하게 되는데, Conversion에 소요되는 비용을 간과할 수는 없다. 또한 물리적인 비용 뿐만이 아니라, Programmer와 설계자, Manager에게 들어가는 교육비용또한 상당하다.

장단점의 적절한 조화

  • 성숙성
Smalltalk이나 C++, 그외의 기존 Programming Language에도 Object-Oriented 방법이 추가되어 새롭게 등장하는 프로그래밍 언어들은 OOPL을 사용하는 데에는 큰 불편함이 없다. 또한 이 새로운 개념을 전문적으로 취급하는 연구단체나 기업이 점점 늘어나고 있으며 이러한 연구단체나 기업들의노력으로 단점을 충분히 파악할 수 있게 되었다.

기존의 방법론과 비교해 보고 싶으면 동일한 Application을 기존의 방법을 이용하는 또다른 Team에게 맡겨보면 된다. 아마도 세가지 정도의 Application을 완성할 때 쯤 되면 Object-Oriented 방법의 장단점을 명확하게 파악할 수 있을 것이다. 이때 주의할 점은, Team 구성원 누구에게도 자신들이 시험의 대상이 되고 있다는 것을 알게해서는 안된다는 것이다. Heroic Effect(자신들이 시험의 대상이 되고 있다는 사실이 평소보다 더 열심히 한다든가 하는 등의 영향요소로 작용제로 Application을 개발할 때보다 수정하는 경우에 비용이 더 많이 소요되는 경우)가 종종 있기 때문이다.

객체지향은 패러다임의 변화를 요구하게 된다. 이 패러다임의 이해도에 따라서 개발자간에 커뮤니케이션 하는데 어려움이 생길 수 있다. 이차이는 개발자의 코딩능력과는 별개다. 십수년의 경력을 가지고 있다고 하더라도 객체지향적으로 프로그램을 만들어오지 않았다면 커뮤니케이션에 어려움이 생길 수 있다. 이러한 개발자간 커뮤니케이션의 문제점은 패턴(:12)에 대한 학습을 선행함으로써 상당부분 해결 가능하다.

관련글