서문
아기들의 막대기 실험 > 두 개의 막대기를 하나인 것처럼 보이도록 실험
사람은 태어난 지 얼마 안 된 시기부터 뚜렷한 경계를 가지고 함께 행동하는 물체를 하나의 개념으로 인지한다.
객체지향과 인지 능력
인간은 세상을 독립적으로 식별 가능한 객체의 집합으로 바라보기 때문에, 객체지향 또한 이해하기 쉬운 패러다임이다. 객체지향은 인간의 기본적인 인지 능력에 기반을 두고 있기 때문이다.
인간은 구체적인 것을 넘어서서 추상적인 것 까지도 객체로 인식할 수 있다.
오늘의 주문 내역과 어제의 주문 내역을 쉽게 구분할 수 있다.
인간은 최대한 더 단순한 객체들로 주변을 분해함으로써 세상을 이해하려고 노력한다. 따라서 객체는 인간이 분명하게 인지하고 구별할 수 있는 물리적, 개념적 경계를 지닌 것이다.
그러나 1장: 협력하는 객체들의 공동체에서 작성한 것 처럼, 소프트웨어 세상에서의 객체는 실생활에서의 것과 의미가 다를 수 있다. 객체지향은 새로운 세계를 창조하는 것이기 때문이다.
객체, 그리고 이상한 나라
이상한 나라의 앨리스를 객체지향적으로 생각해 보자.
앨리스는 정원으로 들어가는 문에 자신의 크기를 맞추기 위해 자신의 키를 조절했다.
앨리스의 상태는 앨리스의 키를 의미한다.
앨리스는 '마셔라' 글자가 인쇄된 음료를 먹거나 케이크를 먹거나 다른 행동을 하면서 키를 조절할 수 있다.
앨리스의 키 (상태)를 변화시키는 것은 앨리스의 행동이다.
앨리스가 문을 통과하기 위해서는 충분한 키를 가지고 있어야 한다.
어떤 행동 (문을 통과)의 성공 여부는 이전에 어떤 행동들 (키를 조절하는 것)이 발생했는지에 영향을 받는다. 즉, 행동 간의 순서가 중요하다.
앨리스가 앨리스라는 사실은 변하지 않는다.
앨리스가 어떠한 행동을 하더라도 앨리스는 앨리스이다. 즉, 유일하게 식별 가능하다.
객체의 상태를 결정하는 것은 행동이지만 행동의 결과를 결정하는 것은 상태다.
객체, 그리고 소프트웨어 나라
객체는 상태, 행동, 식별자를 지닌다.
상태
행동의 성공 여부는 이전에 어떤 행동들이 발생했는지에 영향을 받는다. 그러나 과거의 이력을 모두 기억하고 있는 것은 복잡하다. 때문에 이를 단순화하기 위해 상태라는 개념을 고안했다.
단순한 값들은 객체가 아니다. 이것들은 다른 객체의 특성을 표현하는 데 사용될 뿐이다. 예시로 앨리스의 키는 앨리스 객체의 특성을 표현하는 데 사용된다.
가끔은 단순한 값이 아니라 객체를 이용해 다른 객체의 특성을 표현할 수도 있다. 앨리스 객체가 음료 객체를 가지고 있는지로 설명할 수 있겠다.
단순한 값 (속성)과 객체를 이용해 객체의 상태를 표현할 수 있다.
- 프로퍼티는 객체의 상태를 구성하는 모든 특징을 뜻하며, 정적이다. (ex: 키)
- 프로퍼티 값은 각각의 프로퍼티의 값을 의미하며, 동적이다. (ex: 키의 수치)
- 다른 객체와의 연결은 링크라고 하며, 이 링크를 통해서 메시지를 주고받을 수 있다. 따라서 링크가 있어야 다른 객체와 협력이 가능하다.
행동
객체가 취하는 행동은 객체 자신의 상태를 변경한다. > 행동을 할 때 부수 효과 (side effect)가 발생한다.
객체는 협력에 참여하기 위해 자신만의 방법 (메서드)으로 행동한다고 하였다. 결과적으로 협력에 참여하며 자신의 상태가 변경된다. 때로는 다른 객체에게도 상태를 변경해 달라고 요청하기도 한다.
앨리스가 음료를 마시는 행동을 할 때는 음료 객체의 양 또한 줄어들어야 한다.
그러나 요청을 보낸 객체는 요청을 받은 객체의 상태가 변화될지 알 수 없다. 요청을 받은 객체는 자신만의 방법으로 요청을 처리하기 때문이다. 따라서 요청받은 객체의 상태는 변경되지 않을 수도 있다. 이는 자율성을 보장받아야 하기 때문이다.
상태를 외부에 노출시키지 않고 행동을 경계로 캡슐화하는 것은 결과적으로 객체의 자율성을 높이며, 자율성이 높아질수록 객체의 지능이 높아진다. 협력에 참여하는 객체들의 지능이 높아질수록 협력은 유연하고 간결해지기 마련이다.
식별자
식별자는 객체가 가지고 있는 프로퍼티 중 다른 객체와 구별되기 위해 사용되는 특정한 프로퍼티이다. 식별자를 기반으로 객체가 같은지를 판단할 수 있는 성질을 동일성 (identical)이라고 한다.
어린 시절의 나와 현재의 나는 동일한 나다.
객체를 비교할 때 상태를 이용해 비교할 수 없는 이유는 객체의 상태는 변할 수 있기 때문이다.
객체의 키가 변한다고 해서 객체 자체가 바뀌지는 않는다.
반대로 단순한 값은 식별자를 가지고 있지 않으며 상태만 가지고 있다.
단순한 값의 상태는 변하지 않는다. 때문에 값을 비교할 때는 상태를 이용해 비교하며, 이를 동등성 (equality)이라고 한다.
키가 170에서 180으로 변경되었다면 이것은 값 자체가 변한 것이다. 따라서 170과 180은 일치하지 않는다!
객체지향의 세계는 상태가 변하지 않는 값과 상태가 변하는 객체들이 서로 균형을 맞추며 조화를 이루어야 하는 사회여야 한다.
기계로서의 객체
객체의 상태를 조회하는 작업을 쿼리 (query)라고 하며, 객체의 상태를 변경하는 작업을 명령 (command)이라고 한다.
객체 기계는 객체지향을 효과적으로 설명하기에 적합하다.
사용자는 버튼을 통해서만 객체의 상태를 조회하거나 변경을 "요청"할 수 있다. 어떤 방식을 사용할지는 기계 스스로 결정한다. 이는 객체의 자율성과 관련되어 있다.
기계를 뜯어보지 않는 이상, 기계가 어떤 원리로 로직을 수행하는지 알 수 없다. 또한 쿼리 버튼을 제외하고는 객체의 상태를 알 수 없다. 이는 캡슐화와 관련되어 있다.
서로 다른 두 기계가 있을 때, 이 기계들은 다를 수밖에 없다. 즉, 객체가 구분 가능한 식별자를 가진다는 것을 의미한다.
기계는 연결된 다른 기계에게 요청을 전송할 수 있다. 이는 객체 간에 메시지 전송을 통해 협력하고 있는 것을 의미한다.
행동이 상태를 결정한다
상태를 중심으로 객체를 바라보는 행위 (상태를 먼저 결정하고 그에 대한 행동을 결정하는 행위)는 설계에 나쁜 영향을 미친다.
상태를 먼저 결정할 경우 캡슐화가 저해된다.
객체의 상태가 공용 인터페이스에 노출될 확률이 늘어난다.
객체를 고립된 섬으로 만든다.
객체의 존재 이유는 다른 객체와 협력하기 위해서다.
객체의 재사용성이 저해된다.
객체의 재사용성은 객체가 다양한 협력에 참여할 수 있는 것에서 나온다. 객체를 고립된 섬으로 만듦으로써 객체를 협력에 참여하기 부적절한 요소로 만들기 때문에 객체의 재사용성 또한 저해된다.
따라서 상태가 아니라 행동을 중심으로 객체를 바라봐야 한다.
객체지향 설계는 다음과 같은 방식으로 진행되어야 한다.
- 애플리케이션에 필요한 협력을 생각하라.
- 협력에 필요한 행동들을 생각하라.
- 행동을 수행할 적절한 객체를 선택하라.
- 행동이 결정되면 그 행동을 수행할 때 필요한 정보가 무엇인지 고려하게 된다.
- 이때 필요한 상태가 결정된다. 즉, 행동이 상태를 결정한다.
이는 책임 주도 설계 (Responsibility Driven Design)와 관련 있다. 책임 주도 설계는 협력이라는 문맥 안에서 객체의 행동을 생각하도록 도움으로써 응집도 높고 재사용 가능한 객체를 만들 수 있게 한다.
은유와 객체
객체지향이 단순한 현실 세계의 모방이 아닌 이유 중 하나는 현실 속에서 수동적인 존재가 객체지향 세계에서는 능동적인 존재가 될 수 있기 때문이다. 이는 객체를 의인화 (anthropomorphism) 하였기 때문이다.
계속 언급했듯이 모든 객체는 충분한 자율성을 보장받는다.
전통적으로는 현실 세계의 객체를 자세히 관찰하고 그중에서 소프트웨어 객체에 적합한 속성만 추려내라는 것을 조언했었다.
그러나 이 생각은 객체 지향의 세계가 현실을 반영해야 한다는 의도를 내포하고 있다.
말했듯이, 객체 지향 세계는 새로운 세계를 창조하는 것이다. 그렇다면 현실 세계와 완전히 분리된 세계를 창조하는 것인가? 그것은 아니다. 단지 객체 지향 세계는 현실 세계를 은유 (metaphor)할 뿐이다.
은유를 사용하는 이유는 무엇인가? 은유를 사용하여 현실 세계의 객체를 객체 지향 세계에서 사용할 경우, 그 의미를 우리가 쉽게 파악하고 유추할 수 있기 때문이다. 일례로 전화기 객체는 이 객체가 전화를 걸 수 있다는 사실을 유추할 수 있을 것이다. 방화벽 객체는 이 객체가 이부의 침입을 보호할 수 있다는 사실을 유추할 수 있을 것이다.
이는 코드를 작성할 때 유지보수도 용이하게 해 준다.
다만 이는 현실 세계와 관련이 있을 때 사용하는 방식이다. 만약 현실 세계와 유사성이 없다면 현실을 무시하고 자유롭게 세계를 구축하라.
요약
- 객체의 상태를 결정하는 것은 행동이지만 행동의 결과를 결정하는 것은 상태다.
- 객체는 상태, 행동, 식별자를 가진다.
- 객체를 이루고 있는 요소는 단순한 값과 다른 객체로 구분된다.
- 상태 중심으로 설계하기보다는 행동 중심으로 설계하라. 객체의 존재 이유는 협력을 통해 애플리케이션을 구축하기 위해서이며, 협력을 하기 위한 방법이 곧 행동이기 때문이다.
- 필요한 협력을 생각하고, 그 협력을 이루기 위한 행동들을 생각하고, 행동하기에 적절한 객체를 선택하며, 행동을 수행할 때 필요한 상태를 결정하는 방식으로 애플리케이션을 설계하라.
- 현실 세계와 객체 지향 세계의 관계는 은유이다. 이는 강제적인 것이 아니다. 단지 그 의미를 쉽게 파악할 수 있기 때문이다. 필요하지 않다면 사용하지 않아도 된다.
'도서 📚 > 📗 객체지향의 사실과 오해' 카테고리의 다른 글
6장: 객체 지도 (0) | 2023.11.08 |
---|---|
5장: 책임과 메시지 (0) | 2023.11.07 |
4장: 역할, 책임, 협력 (0) | 2023.11.05 |
3장: 타입과 추상화 (1) | 2023.11.02 |
1장: 협력하는 객체들의 공동체 (2) | 2023.10.31 |