객체지향 패러다임은 지식을 추상화하고 추상화한 지식을 객체 안에 캡슐화함으로써 실세계 문제에 내재된 복잡성을 관리하려고 한다. 객체를 발견하고 창조하는 것은 지식과 행동을 구조화하는 문제다.
- 레베카 워프스브록(Rebecca Wirfs-Borck)[Wirfs-Brock 1990]
객체지향 패러다임은 현실 세계의 존재를 소프트웨어 세계의 객체로 바꾸는 것이다. 그리고 이것은 좋은 방법이며 둘 다 일치한다 => 오해
객체지향 패러다임의 목적은 현실 세계를 모방하는 것이 아니라 현실 세계를 기반으로 새로운 세계를 창조하는 것이다 => 사실
객체지향과 인지 능력
인간은 본능적으로 세상을 독립적이고 식별 가능한 객체의 집합으로 바라본다. 많은 사람들이 객체지향을 직관적이고 이해하기 쉬운 패러다임이라고 말하는 이유는 객체지향이 세상을 자율적이고 독립적인 객체들로 분해할 수 있는 인간의 기본적인 인지 능력에 기반을 두고 있기 때문이다.
세상을 더 작은 객체로 분해하는 것은 본질적으로 세상이 포함하고 있는 복잡성을 극복하기 위한 인간의 작은 몸부림이다. 인간은 좀 더 단순한 객체들로 주변을 분해함으로써 자신이 몸담고 있는 세상을 이해하려고 노력한다. 즉, 객체란 인간이 분명하게 인지하고 구별할 수 있는 물리적인 또는 개념적인 경계를 지닌 어떤 것이다.
객체지향 패러다임의 목적은 현실 세계를 모방하는 것이 아니라 현실 세계를 기반으로 새로운 세계를 창조하는 것이다. 현실 세계의 전등은
사람의 손길 없이는 스스로 불을 밝힐 수 없지만, 소프트웨어 세계의 전등은 외부의 도움 없이도 스스로 전원을 켜거나 끌 수 있다.
실행 중인 객체지향 애플리케이션의 내부를 들여다볼 수 있으면 겉으로는 우리가 알고 있는 세계와 유사해 보이지만 본질적으로는 매우 이질적인 모습을 지닌 세계와 마주치게 될 것이다.
아마 그 세계는 마치 토끼를 뒤쫓던 한 소녀가 경험한 이상한 나라만큼이나 낯설고 기묘할 것이다.
객체, 그리고 이상한 나라
- 이상한 나라의 앨리스
1862년 영국의 수학자였던 찰스 루트위지 도지슨과 그의 친구인 로빈슨 덕워스 목사는 앨리스 리델이라는 소녀에게 한 이야기를 들려주었다.
몇 년이 지난 후 도지슨은 루이스 캐럴(Lewis Carroll)이라는 필명으로 소녀에게 해주었던 이야기를 책으로 출간했다.
이 책이 바로 전 세계 어린이들에게 꾸준한 사랑을 받아온 <이상한 나라의 앨리스(Alice's Adventures in Wonderland)>이다.
앨리스의 이야기를 요약하면 앨리스 본인이, 혹은 다른 생명체에 의해서 앨리스의 키를 늘리거나 줄여가면서 아름다운 정원으로 발길을 향하는 이야기이다.
- 앨리스 객체
앞의 이야기는 앨리스가 겪고 있는 키의 변화에 초점을 맞추고 있다. 앨리스의 키는 시간의 흐름에 따라 계속 변한다. 그렇다고 해서 앨리스의 키가 아무런 이유 없이 변하는 것은 아니다.
앨리스의 키는 앨리스가 '마셔라'라는 커다란 글자가 인쇄된 병 속의 음료를 마시거나 토끼가 떨어뜨린 부채로 부채질을 하거나 쐐기벌레가 알려준 버섯의 한 쪽 부분을 먹으면 작아지고, 상자 속의 케이크를 먹거나 버섯의 반대부분을 먹으면 커진다.
결국 앨리스의 키를 변화시키는 것은 앨리스의 행동이다. 앨리스가 하는 행동에 따라 앨리스의 상태가 변하게 된다.
앨리스의 상태를 결정하는 것은 행동이지만, 행동의 결과를 결정하는 것은 상태이다. 앨리스가 한 행동의 결과는 앨리스의 상태에 의존적이다.
문을 통과한다는 행동의 결과는 앨리스의 위치라는 상태를 이용해 쉽게 설명할 수 있다.
어떤 행동의 성공 여부는 이전에 어떤 행동들이 발생했는지에 영향을 받는다는 사실도 알아두자. 앨리스가 문을 성공적으로 통과하기 위해서는 문을 통과할 수 있을 정도로 충분히 몸을 작게 줄여야 한다. 따라서 앨리스는 문을 통과하기 전에 먼저 키를 작게 줄이기 위해 병 안의 음료나 케이크를 먹어야 한다.
이것은 행동 간의 순서가 중요하다는 것을 의미한다.
행동에 의해 앨리스의 상태가 변경되더라도 앨리스가 앨리스라는 사실은 변하지 않는다. 앨리스의 키가 커지거나 작아지는 것과는 상관 없이 주변 사람들은 앨리스를 앨리스라고 부른다. 따라서 앨리스는 상태 변경과 무관하게 유일한 존재로 식별 가능하다.
앨리스의 특징을 요약해보면
1. 앨리스는 상태를 가지며 상태는 변경 가능하다
2. 앨리스의 상태를 변경시키는 것은 앨리스의 행동이다
- 행동의 결과는 상태에 의존적이며 상태를 이용해 서술할 수 있다
- 행동의 순서가 결과에 영향을 미친다
3. 앨리스는 어떤 상태에 있더라도 유일하게 식별 가능하다
이 이상한 나라에 떨어진 앨리스는 객체지향 세계에 떨어진 객체들과 중요한 공통점 몇 가지를 공유한다.
객체, 그리고 소프트웨어 나라
하나의 개별적인 실체로 식별 가능한 물리적인 또는 개념적인 사물은 어떤 것이라도 객체가 될 수 있다.
객체의 다양한 특성을 효과적으로 설명하기 위해서는
객체를 상태(state), 행동(behavior), 식별자(identity)를 지닌 실체로 보는 것이 가장 효과적이다.
- Booch[2007]
이상한 나라의 앨리스는 상태, 행동, 식별자를 지닌 실체다. 그리고 소프트웨어 안에서 창조되는 객체 역시 상태, 행동, 식별자를 지닌다.
이 책에서는 객체를 다음과 같이 정의하기로 한다.
객체란 식별 가능한 개체 또는 사물이다. 객체는 자동차처럼 만질 수 있는 구체적인 사물일 수도 있고, 시간처럼 추상적인 개념일 수도 있다. 객체는 구별 가능한 식별자, 특징적인 행동, 변경 가능한 상태를 가진다. 소프트웨어 안에서 객체는 저장된 상태와 실행 가능한 코드를 통해 구현된다.
- 상태
- 왜 상태가 필요한가
상태를 이용하면 과거의 모든 행동 이력을 설명하지 않고도 행동의 결과를 쉽게 예측하고 설명할 수 있다.
상태를 이용하면 과거에 얽매이지 않고 현재를 기반으로 객체의 행동 방식을 이해할 수 있다.
상태는 근본적으로 세상의 복잡성을 완화하고 인지 과부하를 줄일 수 있는 중요한 개념이다.
- 상태와 프로퍼티
앨리스가 문을 통과하면서 겪게 되는 소동 속에는 객체라고 부를 수 있는 다양한 사물들이 출현한다. 앨리스는 객체다. 앨리스의 키를 줄이거나 늘리기 위해 사용하는 음료, 케이크, 부채, 버섯 모두 객체다. 토끼는 객체이며 문 역시 객체다. 이들은 뚜렷한 경계를 가지며 식별 가능하고 상태와 행동을 지니고 있다.
그러나 세상에 존재하는 모든 것들이 객체인 것은 아니다. 분명하게 인식할 수 있음에도 객체의 영역에 포함시킬 수 없는 것들도 존재한다.
앨리스의 '키'와 '위치'는 객체가 아니다. 음료와 케이크의 '양'은 객체가 아니다. 문이 열려있는지 '여부'는 객체가 아니고, 토끼가 달려가는 '속도'역시 객체가 아니다.
앨리스가 음료를 마시기 위해 병을 들고 있는 상태를 가정해보자. 객체지향 관점에서 앨리스는 음료에 관해 알고 있는 상태이며, 앨리스 객체와 음료 객체는 서로 연결돼 있다.
* 음료를 마시기 전
앨리스 ( 키 = 130cm, 위치 = "통로" ) <---------------> 음료 ( 양 = 0.5 L )
* 음료를 마신 후
앨리스 ( 키 = 40cm, 위치 = "정원" ) 음료 ( 양 = 0.5 L )
결론적으로 모든 객체의 상태는 단순한 값과 객체의 조합으로 표현할 수 있다.
이때 객체의 상태를 구성하는 모든 특징을 통틀어 객체의 프로퍼티(property)라고 한다. [ 앨리스의 경우 키, 위치, 음료가 앨리스의 프로퍼티가 된다 ]
일반적으로 프로퍼티는 변경되지 않고 고정되기 때문에 '정적'이다.
반면에 프로퍼티 값(property valeu)은 시간이 흐름에 따라 변경되기 때문에 '동적'이다.
음료를 마시기 전에는 앨리스와 음료 사이에 선이 존재했지만, 마신 후에는 선이 사라졌다. 이것은 마신 후의 시점에서는 음료에 관해 알지 못하는 상태로 변경됐음을 의미한다.
이처럼 객체와 객체 사이의 의미 있는 연결을 링크(link)라고 한다. 객체와 객체 사이에는 링크가 존재해야만 요청을 보내고 받을 수 있다.
즉, 객체의 링크를 통해서만 메시지를 주고받을 수 있다.
링크와는 달리 객체를 구성하는 단순한 값은 속성(attribute)이라고 한다. 앨리스의 키와 위치는 단순한 값으로 표현되기 때문에 속성이다.
객체의 프로퍼티는 단순한 값인 속성과 다른 객체를 가리키는 링크의 두 가지 조합으로 표현할 수 있다.
- 객체의 프로퍼티: 속성(attribue) + 연관관계의 두 가지 종류로 구분된다(연관관계: 정적인 관계를 의미, 링크는 연관관계의 인스턴스)
이 책에서는 객체의 상태를 다음과 같이 정의하기로 한다.
상태는 특점 시점에 객체가 가지고 있는 정보의 집합으로 객체의 구조적 특징을 표현한다. 객체의 상태는 객체에 존재하는 정적인 프로퍼티와 동적인 프로퍼티 값으로 구성된다. 객체의 프로퍼티는 단순한 값과 다른 객체를 참조하는 링크로 구분할 수 있다.
객체는 자율적인 존재이다.
객체지향의 세계에서 객체는 다른 객체의 상태에 직접적으로 접근할 수도, 상태를 변경할 수도 없다. 자율적인 객체는 스스로 자신의 상태를 책임져야 한다.
객체는 스스로의 행동에 의해서만 상태가 변경되는 것을 보장함으로써 객체의 자율성을 유지한다.
- 행동
- 상태와 행동
객체의 상태는 저절로 변경되지 않는다. 객체의 상태를 변경하는 것은 객체의 자발적인 행동 뿐이다.
상태와 행동 사이의 관계
- 객체의 행동은 상태에 영향을 받는다
- 객체의 행동은 상태를 변경시킨다
상태라는 개념을 이용해 행동을 다음의 두 가지 관점에서 서술 가능
- 상호작용이 현재의 상태에 어떤 방식으로 의존하는가
- 상호작용이 어떻게 현재의 상태를 변경하는가
- 협력과 행동
어떤 객체도 섬이 아니다.
객체는 자신에게 주어진 책임을 완수하기 위해 다른 객체를 이용하고 다른 객체에게 서비스를 제공한다. 객체는 다른 객체와 적극적으로 상호작용하며 '협력하는 객체들의 공동체'에 참여하기 위해 노력한다.
객체는 다른 객체와 메시지를 통해서만 의사소통할 수 있다.
객체의 행동으로 인해 발생하는 결과는 두 가지 관점에서 설명 가능
- 객체 자신의 상태 변경
- 행동 내에서 협력하는 다른 객체에 대한 메시지 전송
이 책에서는 행동을 다음과 같이 정의한다.
행동이란 외부의 요청 또는 수신된 메시지에 응답하기 위해 동작하고 반응하는 활동이다. 행동의 결과로 객체는 자신의 상태를 변경하거나 다른 객체에게 메시지를 전달할 수 있다. 객체는 행동을 통해 다른 객체와의 협력에 참여하므로 행동의 외부에 가시적이어야 한다.
- 상태 캡슐화
객체는 상태를 캡슐안에 감춰준 채 외부로 노출하지 않는다.
객체가 외부에 노출하는 것은 행동뿐이다.
--> 객체의 행동을 유발하는 것은 외부로부터 전달된 메시지지만 객체의 상태를 변경할지 여부는 객체 스스로 결정한다.
송신자가 상태변경을 기대하더라도 수신자가 자신의 상태를 변경하지 않는다면 송신자가 간섭할 수 있는 여지는 없다.
상태를 외부에 노출시키지 않고 행동을 경계로 캡슐화하는 것은 결과적으로 객체의 자율성을 높인다.
결론적으로 상태를 잘 정의된 행동 뒤로 캡슐화하는 것은 객체의 자율성을 높이고 협력을 단순하고 유연하게 만든다. 이것이 상태를 캡슐화해야 하는 이유다.
- 식별자
객체란 인간의 인지 능력을 이용해 식별 가능한 경계를 가진 모든 사물을 의미한다. 객체가 식별 가능하다는 것은 객체를 서로 구별할 수 있는 특정한 프로퍼티가 객체 안에 존재한다는 것을 의미한다.
이 프로퍼티를 식별자라고 한다. 모든 객체는 식별자를 가지며 식별자를 이용해 객체를 구별할 수 있다.
모든 객체가 식별자를 가진다는 것은 반대로 객체가 아닌 단순한 값은 식별자를 가지지 않든다는 것을 의미한다.
값(value)은 숫자, 문자열, 날짜, 시간, 금액 등과 같이 변하지 않는 양을 모델링한다. 흔히 값의 상태는 변하지 않기 때문에 불변 상태(immutable state)를 가진다고 말한다. 값의 경우 두 인스턴스의 상태가 같다면 두 인스턴스를 같은 것으로 판단한다.
값이 같은지 여부는 상태가 같은지를 이용해 판단한다. 값의 상태가 같음녀 두 인스턴스는 동일한 것으로 판단하고 상태가 다르면 두 인스턴스는 다른 것으로 판단한다. 이처럼 상태를 이용해 두 값이 같은지 판단할 수 있는 성질을 동등성(equality)이라고 한다.
상태를 이용해 동등성을 판단할 수 있는 이유는 값의 상태가 변하지 않기 때문이다.
객체는 시간에 따라 변경되는 상태를 포함하며, 행동을 통해 상태를 변경한다. 따라서 객체는 가변 상태(mutable state)를 가진다고 말한다. 타입이 같은 두 객체의 상태가 완전히 똑같더라도 두 객체는 독립적인 별개의 객체로 다뤄져야 한다. 이름이 앨리스이고 키가 동일한 두 사람이 함께 있다고 하더라도 어떤 누구도 두 사람을 같은 사람이라고 생각하지 않는다. 비록 이름과 키 등의 상태는 완전히 동이랗지만 두 사람은 완전히 별개의 인격체다.
객체 역시 사람과 유사하게 상태와 무관하게 두 객체를 동일하거나 다르다고 판단할 수 있는 프로퍼티를 가진다. 두 객체의 상태가 다르더라도 식별자가 같다면 두 객체를 같은 객체로 판단할 수 있다. 이처럼 식별자를 기반으로 객체가 같은지를 판단할 수 있는 성질을 동일성(identical)이라고 한다.
식별자란 어떤 객체를 다른 객체와 구분하는 데 사용하는 객체의 프로퍼티다. 값은 식별자를 가지지 않기 때문에 상태를 이용한 동등성 검사를 통해 두 인스턴스를 비교해야 한다. 객체는 상태가 변경될 수 있기 때문에 식별자를 이용한 동일성 검사를 통해 두 인스턴스를 비교할 수 있다.
식별자를 가지는 객체로는 참조객체(Reference Object), 엔티티(Entity)가 있고,
식별자를 가지지 않는 값을 가리키는 용어로는 값 객체(Value Object)가 있다.
기계로서의 객체
일반적으로 객체의 상태를 조회하는 작업을 쿼리(query)라고 하고 객체의 상태를 변경하는 작업을 명령(command)이라고 한다.
객체가 외부에 제공하는 행동의 대부분은 쿼리와 명령으로 구성된다.
버트란드 마이어는 'Object-Oriented Software Constuction'[Meyer 2000]에서 객체를 우리가 친숙하게 알고 있는 사물인 기계에 비유해서 표현한다.
사각형 버튼은 이 기계의 상태를 변경하며(앨리스의 경우 '음료를 마시다', '케이크를 먹다', '부채질하다', '버섯을 먹다', '문을 통과하다' 등)
타원형의 버튼은 초록색에 이 기계의 상태를 표시한다.(앨리스의 경우 '키', '위치')
이 객체 기계에서 사각형 버튼은 상태를 변경하는 명령을, 둥근 버튼은 상태를 조회하는 쿼리를 의미한다. 명령과 쿼리는 객체가 외부에 제공하는 행동이라는 점에 주목하자.
즉, 사용자는 객체가 제공하는 명령 버튼과 쿼리 버튼으로 구성된 인터페이스를 통해서만 객체에 접근할 수 있다.
객체 기계가 제공하는 버튼을 통해서만 상태에 접근할 수 있다는 점은 객체의 캡슐화를 강조한다.
기계 은유를 이용하면 객체의 식별자 역시 효과적으로 설명할 수 있다.
두 기계 모두 디스플레이 창에 동일한 숫자인 130을 표시하고 있다. 두 기계는 외부에 동일한 행동을 제공하고 현재의 시점에서 상태 역시 동일하다. 하지만 두 기계를 보는 모든 사람들은 상태가 동일하더라도 두 기계를 구분된 별개의 객체로 인식한다. 이것은 객체가 상태와 무관하게 구분 가능한 식별자를 가진다는 것을 의미한다.
객체를 기계로서 바라보는 관점은 상태, 행동, 식별자에 대한 시각적인 이미지를 제공하고 캡슐화와 메시지를 통한 협력 관계를 매우 효과적으로 설명한다.
행동이 상태를 결정한다
객체지향에 갓 입문한 사람들이 가장 쉽게 빠지는 함정은 상태를 중심으로 객체를 바라보는 것이다.
초보자들은 먼저 객체에 필요한 상태가 무엇인지를 결정하고 그 상태에 필요한 행동을 결정한다.
안타깝게도 상태를 먼저 결정하고 행동을 나중에 결정하는 방법은 설계에 나쁜 영향을 끼친다.
1. 상태를 먼저 결정할 경우 캡슐화가 저해된다.
상태에 초점을 맞출 경우 상태가 객체 내부로 깔끔하게 캡슐화되지 못하고 공용 인터페이스에 그대로 노출되버릴 확률이 높아진다.
2. 객체를 협력자가 아닌 고립된 섬으로 만든다.
객체가 필요한 이유는 애플리케이션의 문맥 내에서 다른 객체와 협력하기 위해서이다.
3. 객체의 재사용성이 저하된다.
객체의 재사용성은 다양한 협력에 참여할 수 있는 능력에서 나온다. 상태에 초점을 맞춘 객체는 다양한 협력에 참여하기 어렵기 때문에 재사용성이 저하될 수밖에 없다.
협력에 참여하는 훌륭한 객체 시민을 양성하기 위한 가장 중요한 것은 상태가 아니라 행동에 초점을 맞추는 것이다.
협력 안에서 객체의 행동은 결국 객체가 협력에 참여하면서 완수해야 하는 책임을 의미한다. 따라서 어떤 책임이 필요한가를 결정하는 과정이 전체 설계를 주도해야 한다.
책임-주도 설계(Responsibility-Driven Design, RDD)[Wirfs-Brock 2003]는 협력이라는 문맥 안에서 객체의 행동을 생각하도록 도움으로써 응집도 높고 재사용 가능한 객체를 만들 수 있게 한다.
은유와 객체
앞에서 했던 오해와 사실을 다시 말하자면
객체지향 세계는 현실 세계의 모방이다 => 오해
객체지향 세계는 현실 세계의 추상화다 => 오해
흔히 객체지향을 현실 세계의 추상화라고도 하는데, 그 안에는 현실 세계를 모방해서 단순화한다는 의미가 숨어있다.
* 추상화(Abstraction): 실제의 사물에서 자신이 원하는 특성만 취하고 필요 없는 부분을 추려 핵심만 표현하는 행위
모방과 추상화라는 개념만으로는 현실 객체와 소프트웨어 객체 사이의 관계를 깔끔하게 설명하지 못한다. 최초의 객체지향 언어인 시뮬라가 그 이름에서부터 객체지향이 현실 세계를 시뮬레이션한다는 의미를 강하게 표출하고 있다고 하더라도 객체지햐잉 현실을 오롯이 모방하기만 한다는 것은 오해일 뿐이다.
- 의인화
Q. 현실 속의 객체와 소프트웨어 객체 사이의 가장 큰 차이점은?
A. 현실 속에서는 수동적인 존재가 소프트웨어 객체로 구현될 때는 능동적으로 변한다는 것이다.
현실 속의 트럼프 카드는 스스로 뒤집을 수도, 말을 할 수도, 걸을 수도 없다.
레베카 워프스브록은 현실의 객체보다 더 많은 일을 할 수 있는 소프트웨어 객체의 특징을 의인화(anthropomorphism)이라고 부른다.
일상적인 체계에서는 어떤 사건이 일어나기 위해 반드시 인간 에이전트가 필요한 반면 객체들은 그들 자신의 체계 안에서 [능동적이고 자율적인] 에이전트다.
의인화의 관점에서 소프트웨어를 생물로 생각하자. 모든 생물처럼 소프트웨어는 태어나고, 삶을 영위하고, 그리고 죽는다[Wirfs-Brock 1990].
- 은유
객체지향 세계와 현실 세계 사이에는 전혀 상관이 없다 => 오해
다만 모방이나 추상화의 수준이 아닌 다른 관점에서 유사성을 가지고 있을 뿐이다.
현실 세계와 객체지향 세계 사이의 관계를 좀 더 정확하게 설명할 수 있는 단어는 은유(metaphor)다.[Noble 2002]
은유란 실제로는 적용되지 않는 한 가지 개념을 이용해 다른 개념을 서술하는 대화의 한 형태다.
은유는 표현적 차이(Representational Gap) 또는 의미적 차이(Semantic Gap)라는 논점과 관련성이 깊다.
은유 관계에 있는 실제 객체의 이름을 소프트웨어의 객체 이름으로 사용하면 표현적 차이를 줄여 소프트웨어의 구조를 쉽게 예측할 수 있다.
- 이상한 나라를 창조하라
객체지향 설게자로서 우리의 목적은 현실을 모방하는 것이 아니라 현실 속의 객체를 바탕으로 은유를 이용해서 우리들만의 소프트웨어 세계를 창조해야 한다. 마치 앨리스의 이상한 나라처럼말이다.
'Study > 객체지향의 사실과 오해' 카테고리의 다른 글
3장: 타입과 추상화 (0) | 2021.08.16 |
---|---|
1장: 협력하는 객체들의 공동체 (1) | 2021.08.02 |
객체지향의 사실과 오해 스터디 (0) - 시작 & Why? & 목차 (0) | 2021.08.01 |
댓글