영국에 지하철이 처음 생기고 이후 런던 지하철 노선을 쉽게 알아볼 지하철 노선도를 만들었다. 이때 실제 지형도에 맞는 위치에 구불구불한 운행 노선과 불규칙적인 간의 거리를 사실적으로 묘사했다. 결과 노선도는 매우 이해하기 어려웠다

 

지하철 노선도 디자인에서 가장 중요한 것은 얼마나 사실적으로 지형을 묘사했느냐가 아니라 역과 사이의 연결성을 얼마나 직관적으로 표현했느냐다.

해리 벡은 사실적인 지형과 축척은 무시하고 사이의 연결성에만 집중한 지하철 노선도를 창조했다. 노선도는 역의 순서와 갈아타는 역의 표시를 제외하면 어느 하나 정확한 것이 없었다. 하지만 현재까지 계속 쓰이고 있는 것은 해리 벡의 지하철 노선도다.

노선도의 핵심은 정확성을 버리고 목적에 집중한 결과다. 지하철 노선도의 목적은 지형이 아닌 연결이다.(추상화)

 

해리 벡은 지하철 승객들을 면밀하게 관찰해 승객이 알아야 하는 사실만 정확하게 표현하고 몰라도 되는 정보는 무시함으로써 이해하기 쉽고 단순하며 목적에 부합하는 지하철 노선도를 창조해 있었다.

, 지하철 노선을 추상화한 것이다.

 

 

추상화를 통한 복잡성 극복

현실은 복잡하며 예측 불가능한 혼돈의 덩어리다.

나비효과는 현실의 복잡성을 이해하고 예측하는 것이 얼마나 어려운지를 설명해 주는 적절한 메타포다.

 

인간이 지닌 인지 능력과 저장 공간은 현실의 복잡성 전부를 받아들이기에는 부족하다. 따라서 인간은 본능적으로 이해하기 쉽고 예측 가능한 수준으로 현실을 분해하고 단순화하는 전략을 따른다.

 

해리 벡이 고안한 추상화는 지형 정보를 제거하고 사이 연결성을 강조함으로써 지하철 노선도 목적에 맞게 현실을 단순화했다.

 

진정한 추상화란 현실에서 출발하되 불필요한 부분을 도려내 가면서 사물의 놀라운 본질을 드러나게 하는 과정이다

 

만약 런던 곳곳의 정확한 위치와 실제 거리를 알고자 했다면 당연히 초기 런던 지하철 노선도가 적절한 노선도이다. 중요한 것은 목적이다.

 

어떤 추상화도 의도된 목적이 아닌 다른 목적으로 사용된다면 오도될 있다.

현상은 복잡하다. 법칙은 단순하다. 버릴 무엇인지 알아내라.

 

 

이 책에서는 추상화를 다음과 같이 정의한다.

추상화

어떤 양상, 세부 사항, 구조를 좀 더 명확하게 이해하기 위해 특정 절차나 물체를 의도적으로 생략하거나 감춤으로써 복잡도를 극복하는 방법이다.

 

복잡성을 다루기 위해 추상화는 두 자원에서 이뤄진다[Kramer 2007].

• 첫 번째 자원은 구체적인 사물들 간의 공통점은 취하고 차이점은 버리는 일반화를 통해 단순하게 만드는 것이다.

• 두 번째 자원은 중요한 부분을 강조하기 위해 불필요한 세부 사항을 제거함으로써 단순하게 만드는 것이다.

모는 경우에 추상화의 목적은 복잡성을 이해하기 쉬운 수준으로 단순화하는 것이라는 점을 기억하라.

 

객체지향 패러다임은 객체라는 추상화를 통해 현실의 복잡성을 극복한다.

추상화의 차원을 반드시 이해하고 적용하자

 

객체지향과 추상화

모두 트럼프일

엘리스 이야기 예시

앨리스는 분명한 경계를 가지는 식별 가능한 하나의 객체다.

3명의 정원사 역시 객체다. 클로버 병사들 역시 객체다. 하얀 토끼도 객체다.

장면에 객체는 제각기 독특한 모습을 하고 있지만, 앨리스는 객체들 대부분을 하나로 아울러 생각하고 있다. '기껏해야 트럼프에 불과해' 그렇다. 앨리스는 객체들 중에서 하얀 토끼를 제외한 모든 객체를 '트럼프'라는 하나의 개념으로 단순화해서 바라보고 있다.

과감하게 차이점을 무시하고 공통점만 취해 단순화해 버렸다.

그룹으로 나누어 단순화하기

정원사, 병사, 신하, 왕자, 공주, 하객 얼핏 보면 비슷해보이지만 인물들에게는 다양한 측면에서 서로를 구별할 있는 독특한 특징이 있다.

이처럼 명확한 경계를 가지고 서로 구별할 있는 구체적인 사람이나 사물을 객체지향 패러다임에서는 객체라고 한다.

 

앨리스는 인물들을 하나씩 살펴보면서 자신이 알고 있는 '트럼프' 의미에 적합한 인물은 '트럼프'그룹에 포함하고 이외 적합하지 않은 인물은 그룹에서 제외했다.

 

결과적으로 개의 그룹으로 나눴다. 하나는 트럼프 그룹, 나머지 하나는 토끼 그룹이다.

이제 트럼프와 토끼라는 개의 렌즈를 통해 정원을 바라보는 것은 정원에 내재된 복잡성을 효과적으로 감소시킨다.

 

개념

구체적이고 실제적인 객체들 모두를 개별적인 단위로 취급하기에는 인간이 지닌 인지능력은 턱없이 부족하다. 따라서 사람들은 본능적으로 공통적인 특성을 기준으로 객체를 여러 그룹으로 묶어 동시에 다뤄야 하는 가짓수를 줄임으로써 상황을 단순화하려고 노력한다.

 

공통점을 기반으로 객체들을 묶기 위한 그릇을 개념(concept)이라고 한다.

개념이란 일반적으로 우리가 인식하고 있는 다양한 사물이나 객체에 적용할 있는 아이디어나 관념을 뜻한다.

 

개념 적용 예시

길거리를 빠른 속도로 누비는 교통수단 = 자동차 개념 적용

하늘을 나는 교통수단  = 비행기 개념 적용

 

개념을 이용하면 객체를 여러 그룹으로 분류(classification) 있다.

개념은 공통점을 기반으로 객체를 분류할 있는 일종의 체라고 있다.

 

결국 객체는 특정한 개념을 표현하는 그룹의 일원으로 포함된다.

하트 여왕은 트럼프 그룹에 일원

하얀 토끼는 토끼 그룹에 일원

이처럼 객체에 어떤 개념을 적용하는 것이 가능해서 개념 그룹의 일원이 객체를 개념의 인스턴스라고 한다.

 

객체란 특정한 개념을 적용할 있는 구체적인 사물을 의미한다. 개념이 객체에 적용됐을 객체를 개념의 인스턴스라고 한다.

 

개념은 세상의 객체들을 거르는 사용하는 렌즈를 제공한다. 렌즈를 통해 세상을 바라보면 수백 수천 개의 다양한 객체가 존재하는 복잡한 세상을 개의 개념만으로 단순화할 있다.

개념은 객체를 분류할 있는 틀을 제공한다.

 

기계로서의 객체

버트란 마이어의 은유 표현

객체 지향 세계에서 주된 업무는 객체 상태의 상태를 조회하고, 객체의 상태를 변경하는 

일반적으로 객체의 상태를 조회하는 작업을 쿼리(query)

객체의 상태를 변경하는 작업을 명령(command)이라고 한다.

객체가 외부에 제공하는 행동의 대부분은 쿼리와 명령으로 구성된다.

 

기계로서의 객체라는 비유의 의미란 기계의 부품은 단단한 금속 외피 안에 감춰져 있어 분해하지 않는한 기계의 내부를 직접   없다. 그저 외부에 노출된 버튼과 같은 인터페이스를 통해서만 상호작용  있다.

 

둥근 버튼은 디스플레이에 현재 상태 정보를 알려준다. 쿼리

사각 버튼은 상태 변경을 한다. 명령

버튼을 누르는 행위는 메시지를 전송하는 것과 같다. 요청을 처리하는 것은 기계가 자율적으로 판단한다.

기계와 통신은 전적으로 기계가 외부로 노출한 인터페이스로만 이뤄진다. 캡슐화

 기계 상태가 동일하더라도 상태(130) 무관하게 구분이 가능하다.

이것은 구분 가능한 식별자를 가진다는 것을 의미한다.

앨리스 기계에 음료를 마시다 버튼을 눌렀다고 가정하면

앨리스 기계는 내부적으로 키를 작게 변경한  링크를 통해 연결된 음료 기계에게 마셔지다라는 버튼이 눌러지도록 요청을 전송한다.

링크를 통해 연결된  객체가 메시지 전송을 통해 협력하고 있다.

 

 

 

 

행동이 상태를 결정한다.

상태를 먼저 결정하고 행동을 나중에 결정하는 방법은 설계에 안좋다.

첫째, 상태를 먼저 결정할 경우 캡슐화가 저해된다.

둘째, 객체를 협력자가 아닌 고립된 섬으로 만든다.

객체가 필요한 이유는 애플리케이션 문맥 내에서 다른 객체와 협력하기 위함이다.

셋째, 객체의 재사용성이 저하된다.

객체의 재사용성은 다양한 협력에 참여할  있는 능력에서 나온다.

 

행동에 초점을 맞춰야 협력에 참여할  있다.

객체는 다른 객체와 협력하기 위해 존재한다. 행동은 객체가 협력에 참여할  있는 유일한 방법이다.

따라서 상태가 아니라 행동에 초점을 맞춰 객체를 설계해야한다.

 

협력 안에서 객체의 행동은 결국 객체가 협력에 참여하면서 완수해야 하는 책임을 의미한다.

따라서 어떤 책임이 필요한가를 결정하는 과정이 전체 설계를 주도해야 한다.(책임-주도 설계, Responsibility-Driven Design, RDD)

협력이라는 문맥 안에서 객체의 행동을 생각하도록 도움으로써 응집도높고 재사용 가능한 객체를 만들  있게 한다.

 

행동이 상태를 결정한다.

 

 

 

은유와 객체

의인화

현실 객체와 소프트웨어 객체 사이 가장  차이는

현실  수동적 존재가 소프트웨어 속에서는 능동적 존재가 된다는 것이다.

 

일반적으로 현실 세계의 객체에 필요한 부분만을 추상화하여 가상의 객체를 만든다고 한다.(모방)

실제로 소프트웨어 안에 창조하는 객체에게 현실 세계의 객체와는 전혀 다른 특징을 부여하는 것이 일반적이다.

, 소프트웨어 객체가 현실 객체의 부분적인 특징을 모방하는 것이 아니라 현실 객체가 가지지 못한 추가적인 능력을 보유하게 된다.

 

예시

현실  트럼프 카드는 스스로 뒤집거나, 말을   없다. 계좌는 스스로 금액을 이체할  없다.

 

객체지향 세계를 구축할  현실에서 가져온 객체들은 현실 속에서는   없는 어떤 일이라도   있는 전지전능한 존재가 된다.

 

레베카 워프스브록은 현실의 객체보다  많은 일을   있는 소프트웨어 객체의 특징을 의인화(anthropomorphism)라고 부른다

 

객체는 무생물이거나 심지어는 실세계의 개념적인 개제로 모델링될 수도 있지만, 그것들은 마치 우리가

현실 세계에서 에이전트로 행동하는 것처럼 시스템 안에서 에이전트처럼 행동한다. 객체가 현실 세계의

대상보다 더 많이 안다는 것이 모순처럼 보일 수도 있다. 결국, 인간이라는 에이전트 없이 현실의 전화는

서로에게 전화를 걸지 않으며 색은 스스로 칠하지 않는다. 일상적인 체계에서는 어떤 사건이 일어나기

위해 반드시 인간 에이전트가 필요한 반면 객체들은 그들 자신의 제계 안에서 [능동적이고 자율적인] 에

이전트다.

의인화의 관점에서 소프트웨어를 생물로 생각하자. 모는 생물처럼 소프트웨어는 태어나고, 삶을 영위하

고, 그리고 죽는다[Wirfs-Brock 1990].

 

심지어 현실 세계에는 존재조차 하지 않는 것들도 소프트웨어 안에서는 생생한 생명을 가진 존재로 재탄생한다.

 

소프트웨어 상에 구축되는 객체지향 세계는 현실을 모방한 것이 아니다. 현실을 참조할  궁극적인 목적은 현실과 전혀 다른 새로운 세계를 창조하는 것이다.

객체지향의 세계는 현실의 추상화가 아니다. 오히려 객체지향 서계의 거리는 현실 속의 객체보다  많은 특징과 능력을 보유한 객체들로 넘쳐난다.

 

 

은유

객체지향의 세계와 현실 세계 사이에는 전혀 상관이 없는 것인가?

그렇지는 안다. 다만 모방이나 추상화의 수준이 아닌 다른 관점에서 유사성을 가지고 있을 뿐이다.

현실과 객체지향 세계 사이의 관계를   정확하게 설명할  있는 단어는 은유(metaphor)

 

은유란 실제로 적용되지 않는  가지 개념을 이용해 다른 개념을 서술하는 대화의  형태다.

은유의 본질은  종류의 사물을 다른 종류의 사물 관점에서 이해하고 경험하는  있다.

현실  객체의 의미 일부가 소프트웨어 객체로 전달되기 때문에 프로그램 내의 객체는 현실 속의 객체에 대한 은유다.

 

은유는 표현적 차이(representational gap) 또는 의미적 차이(semantic gap)라는 논점과 관련성이 깊다.

여기서 차이는 소프트웨어에 대해 사람들이 생각하는 모습과 실제 소프트웨어의 표현 사이의 차이를 의미한다.

은유 관계에 있는 실제 객체의 이름을 소프트웨어 객체의 이름으로 사용하면 표현적 차이를 줄여 소프트웨어의 구조를 쉡게 예측할  있다.

이런 이유로 현실 시계 도메인에서 사용되는 이름을 객체에게 부여하라고 객체지향 지점서에서 가이드하는 것이다.

 

 

이상한 나라를 창조하라

객체지향 설계자로서 우리의 목적은 현실을 모방하는 것이 아니다.(기존 객체지향 추상화 개념)

단지 이상한 나라를 창조하기만 하면 된다.

현실을 닮아야 한다는 어떤 제약이나 구속도 없다.

여러분이 창조한 객체의 특성을 상기시킬  있다면 현실 속의 객체의 이름을 이용해 객체를 묘사하라.(은유) 그렇지 않다면 깔끔하게 현실을 무시하고 자유롭게 여러분만의 새로운 세계를 창조하기 바란다. 앨리스를 매혹시킨 이상한 나라가 그런  처럼 말이다.

 

 

 

 

행동

상태와 행동

객체의 상태를 변경하는 것은 객체의 자발적인 행동뿐이다.

앨리스의 키가 작아진 이유는 앨리스가 음료를 마신 행동 때문이다.

 

객체의 행동에 의해 객체의 상태가 변경된다는 것은 행동이 부수 효과(side effect) 초래한다는 것을 의미한다.

부수 효과 개념을 이용하면 객체의 행동을 상태 변경의 관점에서 쉽게 기술할 있다.

앨리스가 케이크를 먹는 행위는 앨리스의 키를 작게 변화시키고 케이크의 양을 줄이는 부수 효과를 야기한다.

 

객체의 행동은 객체의 상태를 변경시키지만 행동의 결과는 객체의 상태에 의존적이다.

int sum = 20;  상태

sum = add(sum, 20);  //행동은 상태를 변경시킨다

현재 sum 40// 행동의 결과는 상태에 의존적이다.

 

 

앨리스 과거 행동을 돌아볼 필요 없이 앨리스의 키와 위치라는 상태 값을 이용해 간단하게 서술할 있다.

  • 앨리스의 키가 40센티미터 이하라면 문을 통과할 수 있다.
  • 문을 통과한 후에 앨리스의 위치는 아름다운 정원으로 바뀌어야 한다.

 

상태를 이용하면 복잡한 객체의 행동을 쉽게 이해할 있다.

협력과 행동

객체가 다른 객체와 협력하는 유일한 방법은 다른 객체에게 요청 보내는 것이다.

요청을 수신한 객체는 요청을 처리하기 위한 적절한 행동을 한다.

따라서 객체의 행동은 객체가 협력에 참여할 있는 유일한 방법이다.

 

객체는 협력에 참여하는 과정에서 자기 자신의 상태뿐만 아니라 다른 객체의 상태 변경을 유발할 도있다.

 

객체의 행동은 가지 부수효과를 가질 있다.

  • 객체 자신의 상태 변경
  • 행동 내에서 협력하는 다른 객체에 대한 메시지 전송

행동이란 외부의 요청 또는 수신된 메시지에 응답하기 위해 동작하고 반응하는 활동이다. 행동의 결과로 객체는 자신의 상태를 변경하거나 다른 객체에게 메시지를 전달할 있다. 객체는 행동을 통해 다른 객체와의 협력에 참여하므로 행동은 외부에 가시적이어야 한다.

상태 캡슐화

현실 세계의 객체와 객체지향 세계의 객체 사이에는 차이가 있다.

현실 앨리스는 능동적인 존재로 스스로 음료를 마실 있지만 음료는 스스로는 아무것도 없는 수동적 존재다.

 

객체지향의 세계에서 모든 객체는 자신의 상태를 스스로 관리하는 자율적인 존재다.

, 음료 객체도 자신이 스스로 양을 줄일 있어야 하며, 앨리스 객체가 음료의 상태를 변경 할 없다. 단지 음료 객체에게 자신이 음료를 마셨다는 메시지를 전달할 있을 뿐이다.

앨리스가 음료를 마셨다고 메시지를 보내도 음료의 량을 줄일 지 말지는 음료 객체가 결정할 사항이다. 앨리스는 음료의 양이 줄어들 것이라는 것을 믿고 요청을 전달할 뿐이다.

 

앨리스에게 전달되는 메시지는 drinkBeverage()

음료에게 전달되는 메시지 drunken(quantity)

메시지만 보고 앨리스의 키와 음료의 양이 줄어든다는 상태 변경을 예상할 있나?

전혀 알지 못한다.

 

이것이 캡슐화가 의미하는 것이다. 객체는 상태를 캡슐 안에 감춰둔 외부로 노출하지 않는다. 객체가 외부에 노출하는 것은 행동뿐이며, 외부에서 객체에 접근할 있는 유일한 방법 역시 행동뿐이다.

 

객체의 행동을 유발하는 값은 외부로부터 전달된 메시지지만 객체의 상태를 변경할지 여부는 객체 스스로 결정한다.

사실 객체에게 메시지를 전달하는 외부의 객체는 메시지를 수신하는 객체의 상태가 변경된다는 사실조차 알지 못한다.

메시지 송신자는 단지 자신의 요구를 메시지로 포장해서 전달할 뿐이다. 메시지를 해석하고 그에 반응해서 상태를 변경할지 여부는 전적으로 메시지 수신자의 자율적인 판단에 따른다.

송신자가 상태 변경을 기대하더라도 수신자가 자신의 상태를 변경하지 않는다면 송신자가 간섭할 있는 어떤 여지도 없다.

 

상태를 외부에 노출시키지 않고 행동을 경계로 캡슐화하는 것은 결과적으로 객체의 자율성을 높힌다.

객체의 자율성이 높아질 수록 객체간 협력은 유연하고 간결해진다.

 

결론적으로 상태를 정의된 행동 집합 뒤로 캡슐화하는 것은 객체의 자율성을 높이고 협력을 단순하고 유연하게 만든다. 이것이 상태를 캡슐화해야 하는 이유다.

 

식별자

객체란 인간의 인지 능력을 이용해 식별 가능한 경계를 가진 모든 사물

객체가 식별 가능하다는 것은 객체를 서로 구별할 있는 특정한 프로퍼티 객체 안에 존재한다는 것을 의미한다. 프로퍼티를 식별자 한다.

 

단순한 값과 객체의 가장 차이점은 값은 식별자를 가지지 않지만 객체는 식별자를 가진다.

 

값은 숫자, 문자열, 날짜, 시간, 변하지 않는 양을 모델링한다. 때문에 불변 상태(immutable state) 가진다고 말한다.

 

값이 같은지 여부는 값의 상태를 보고 결정한다. 인스턴스가 같은 상태를 가지면 동일하다고 판단한다. 이처럼 상태를 이용해 값이 같은지 판단할 있는 성질을 동등성(equality)이라 한다.

 

객체는 시간에 따라 변경되는 상태를 포함한다. 행동을 통해 상태를 변경한다.

따라서 객체는 가변 상태(mutable state) 가진다고 말한다.

타입이 같은 객체의 상태가 완전히 똑같더라도 객체는 독립적인 별개의 객체로 다뤄야 한다.

 

객체도 같거나 다르다고 판단할 있는 프로퍼티를 가진다. 객체의 상태가 다르더라도 식별자가 같다면 객체를 같은 객체로 판단할 있다.

이처럼 식별자를 기반으로 객체가 같은지를 판단할 있는 성질을 동일성(identical)이라고 한다.

 

상태를 기반으로 객체의 동일성을 판단할 없는 이유는 시간에 따라 객체의 상태가 변하기 때문이다. 따라서 식별자를 두어 객체의 동일성을 판단하는 것이다.

 

식별자란 어떤 객체를 다른 객체와 구분하는 데 사용하는 객체의 프로퍼티다. 값은 식별자를 가지지 않기 때문에 상태를 이용한 동등성 검사를 통해 두 인스턴스를 비교해야 한다. 객체는 상태가 변경될 수 있기 때문에 식별자를 이용한 동일성 검사를 통해 두 인스턴스를 비교할 수 있다.

 

객체지향 프로그래밍 언어에서 값과 객체의 차이점을 혼동할 수도 있다.

근본적으로 값도 클래스로 표현되기 때문이다. Integer,Boolean…(물론 자바는 기본형도 지원)

때문에 별도의 용어를 쓰는 경우가 있다. 객체는 식별자가 없는 객체이다.

참조객체(reference object) 또는 엔티티(entity) 식별자가 있는 객체

 

지금까지 객체의 중요한 특성인 상태, 행동, 식별자에 대한 요약

객체는 상태를 가지며 상태는 변경 기능하다.

객체의 상태를 변경시키는 것은 객체의 행동이다.

행동의 결괴는 상태에 의존적이며 상태를 이용해 서술할 수 있다.

행동의 순서가 실행 결과에 영향을 미친다.

객체는 어떤 상태에 있더라도 유일하게 식별 기능하다.

 

 

 

 

 

 

 

 

객체지향과 인지 능력

인간은 직접적으로 지각할 있는 사물을 넘어 추상적인 사물까지도 객체로 인식할 있는 능력이 있다. 어제 주문내역과 오늘 주문내역을 구분하는 , 출금 계좌에서 동일한 입금 계좌로 동일한 금액을 이체하더라도 구분이 가능하다.

물리적인 실체는 존재하지 않더라도 인간이 쉽게 구분하고 하나의 단위로 인지할 있는 개념적인 객체의 일종이다.

 

복잡한 세상에서 인간은 단순한 객체들로 주변을 분해함으로써 세상을 이해하려고 노력한다.

, 객체란 인간이 분명하게 인지하고 구별할 있는 물리적인 또는 개념적인 경계를 지닌 어떤 이다.

 

객체지향 패러다임은 인간이 인지할 있는 다양한 객체들이 모여 현실 세계를 이루는 것처럼 소프트웨어의 세계 역시 인간이 인지할 있는 다양한 소프트웨어 객체들이 모여 이뤄져 있다는 믿음에서 출발한다.

객체지향 패더라임의 목적은 현실 세계를 모방하는 것이 아니라 현실 세계를 기반으로 새로운 세계를 창조하는 것이다. 따라서 현실 세계 객체와 소프트웨어 세계의 객체와는 전혀 다른 모습을 보이는 것이 일반적이다.

 

예로 현실세계 전등은 사람없이 껏다 킬수 없다. 소프트웨어 전등은 자동으로 가능하다.

 

객체, 그리고 이상한 나라

이상한 나라의 앨리스

앨리스 이야기로 예시를 든다. 이야기 내용을 요약하면,

작은 문을 통과하기 위해, 주변 음식을 먹으면서 몸집을 줄였다가 늘렸다 한다.

앨리스 객체

앞의 이야기는 앨리스가 겪고 있는 키의 변화에 초점을 맞추고 있다.

앨리스는 정원으로 가기 위해 자신의 상태 계속 변화시켰다.

이런 상태변화는 앨리스의 행동이다. 앨리스 행동에 따라 앨리스 상태가 변한다.

 

상태를 결정하는 것은 행동이지만 행동의 결과를 결정하는 것은 상태이다.

예를들어, 앨리스 130cm 여기에 케이크를 먹어서 150cm 커졌다. 그럼 원래 상태 130cm + 150cm

280cm 된다.

, 앨리스가 행동의 결과는 앨리스의 상태에 의존적이다.

어떤 행동의 성공 여부는 이전에 어떤 행동들이 발생했는지에 영향을 받는다는 사실도 중요하다

앨리스가 문을 성공적으로 통과하기 위해서는 문을 통과할 있을 정도로 충분히 몸을 작게 중여야 한다. 따라서 앨리스는 문을 통과하기 전에 먼저 키를 작게 줄이기 위해 안의 음료나 케이크를 먹어야 한다.

이것은 행동 간의 순서가 중요하다는 것을 의미한다. 문을 통과하는 행동이 성공하려면 음료나 케이크를 먹는 행동이 선행돼야만 한다.

 

 

객체, 그리고 소프트웨어 나라

물리적인 또는 개념적인 사물은 어떤 것이라도 객체가 있다.

인간의 인지 능력 안에서 개수를 있고, 다른 사물과 구분할 있으며, 생성 시점을 있고, 독립적인 하나의 단위로 인식할 있는 모든 사물은 객체다.

 

객체의 다양한 특성을 효과적으로 설명하기 위해선 객체를 상태(state), 행동(behavior), 식별자(identity) 지닌 실체로 보는 것이 가장 효과적이다.

 

책에서 객체를 다음과 같이 정의한다.

객체란 식별 가능한 개제 또는 사물이다. 객체는 자동차처럼 만질 수 있는 구체적인 사물일 수도 있고, 시간처럼 추상적인 개념일 수도 있다. 객체는 구별 가능한 식별자, 특징적인 행동, 변경 가능한 상태를 가진다. 소프트웨어 안에서 객체는 저장된 상태와 실행 가능한 코드를 통해 구현된다.

 

 

상태

상태가 필요한가

객체가 주변 환경과의 상호작용에 어떻게 반응하는가는 시점까지 객체에 어떤 일이 발생했느냐에 좌우된다.

예를들어 비행기를 이용하려면 탑승 전에 발권이 필수다.

자판기에 음료를 먹기위해서는 충분한 돈을 넣어야 한다.

 

공통점은 어떤 행동의 결과는 과거에 어떤 행동들이 일어났었느냐에 의존한다는 것이다.

 

일반적으로 과거에 발생한 행동이력을 통해 현재 발생한 행동의 결과를 판단하는 방식은 복잡하고 번거롭고 이해하기 어렵다.

행동과정과 결과를 단순하게 기술하기 위한 상태라는 개념을 고안했다.

비행기 탑승 가능 여부는 항공권의 발권 상태를 보고 예측할 있다.

자판기는 현재까지 투입된 금액의 상태를 기억한다.

 

상태를 이용하면 과거의 모든 행동이력을 설명하지 않고도 행동의 결과를 쉽게 예측하고 설명할 있다.

앨리스가 과거에 어떤 행동을 했었는지 모르더라도 앨리스의 키만 알면 문을 통과할 있는지 여부를 쉽게 판단할 있다.

앨리스 키와 문높이 두가지 상태만 알면 문을 통과하는 행동의 결과를 쉽게 예측할 있다.

 

 

상태와 프로퍼티

앨리스는 객체다. 앨리스의 키를 줄이거나 늘리기 위해 사용하는 음료, 케이크, 부채, 버섯 모두 객체다. 모두 뚜렷한 경계를 가지며 식별 가능하고 상태와 행동을 지니고 있다.

 

그러나 세상에 모든 것들이 객체인 것은 아니다. 앨리스의 '' 위치' 객체가 아니다. 음료의 '' 객체가 아니다. 문이 열렸는지 '여부' 객체가 아니다

, 숫자, 문자열, , 속도, 시간, 날짜, 참/거짓과 같은 단순한 값들은 객체가 아니다.

단순값들은 자체로 독립적인 의미를 가지기보다는 다른 객체의 특성을 표현하는데 사용된다.

 

때로는 단순한 값이 아니라 객체를 사용해 다른 객체의 상태를 표현해야 때가 있다.

앨리스가 음료를 들고 있는 상태를 표현하기 위해 /거짓이 아닌 음료 객체를 이용해 표현하는 것이다. 음료를 들고있나 없나는 음료객체와 연결됐나 안됐나로 구분한다.

결론적으로 모든 객체의 상태는 단순한 값과 객체의 조합으로 표현할 있다.

객체의 상태를 구성하는 모든 특징을 통틀어 객체의 프로퍼티(property)라고 한다.

앨리스 기준 ,위치,음료가 프로퍼티다.

일반적으로 프로퍼티는 변하지 않는 정적이다. 반면 프로퍼티의 값은 변할 있는 동적이다.

 

다른 시점에서 앨리스를 봤는데 음료와 연결이 없다. 음료를 버린 것으로 보인다.

시점에서 앨리스는 음료에 대한 상태를 모른다.

이처럼 객체와 객체 사이의 의미 있는 연결을 링크(link)라고 한다.

 

객체 사이 링크를 통해서만 요청을 주고 응답을 받을 있다.

, 링크를 통해서만 협력이 가능하다

 

객체 간의 선으로 표현되는 링크와 달리 객체를 구성하는 단순 값은 속성(attribute)이라고 한다.

따라서 앨리스의 키와 위치는 속성이다.

 

조합하면 프로퍼티는 단순 값인 속성과 객체와 연결을 가르키는 링크 조합이다.

 

이 책에서는 객체의 상태를 다음과 같이 정의하기로 한다.

상대는 특정 시점에 객체가 가지고 있는 정보의 집합으로 객체의 구조적 특징을 표현한다.

객체의 상태는 객체에 존재하는 정적인 프로퍼티와 동적인 프로퍼티 값으로 구성된다.

객체의 프로퍼티는 단순한 값과 다른 객체를 참조하는 링크로 구분할 수 있다.

 

객체는 자율적인 존재라는 것을 명심하라

객체지향의 세계에서 객체는 다른 객체의 상태에 직접적으로 접근할 수도, 상태를 변경할 수도 없다.

자율적인 객체는 스스로 자신의 상태를 책임져야 한다.

외부의 객체가 직접적으로 객체의 상태를 주무를 없다면 간접적으로 객체의 상태를 변경하거나 조회 있는 방법이 필요하다.

 

행동은 다른 객체로 하여금 간접적으로 객체의 상태를 변경하는 것을 가능하게 한다.

객체지향의 기본 사상은 상태와 상태를 조작하기 위한 행동을 하나의 단위로 묶는 것이라는 점을 기억하라

객체는 스스로의 행동에 의해서만 상태가 변경되는 것을 보장함으로써 객체의 자율성을 유지한다.

 

 

 

 

 

협력 속에 사는 객체

역할, 책임, 협력

실제로 협력에 참여하는 주체는 객체.

실행 중 인 어플리케이션을 보면 객체들간에 메시지를 주고받으면서 협력하는 것을 있다. 이렇듯 객체가 없으면 객체지향 세계 역시 아무런 의미가 없다. 객체지향이라 부르는 이유는 패러다임의 중심에 객체가 있기 때문이다.

 

객체는 애플리케이션의 기능을 구현하기 위해 존재한다. 작은 기능조차 객체 혼자 감당하기에는 버거울 정도로 복잡 거대하다. 때문에 객체는 다른 객체와의 협력을 통해 기능을 구현하게 된다.

따라서 협력이 얼마나 조화를 이루는지 결정하는 것은 객체다.

결국 협력의 품질을 결정하는 것은 객체의 품질이다.

 

협력 공동체의 일원으로 객체는 가지 덕문을 갖춰야 한다.

첫째, 객체는 충분히 협력적이어야 한다.

모든 것을 스스로 처리하려고 하는 전지전능한 객체는 내부적인 복잡도에 의해 자멸하고 만다

 

둘째, 객체가 충분히 자율적이어야 한다.

자기 스스로의 원칙에 따라 어떤 일을 하거나 자기 스스로를 통제하여 절제하는 것을 의미한다.

객체는 다른 객체에 명력에 복종하는 것이 아니라 요청에 응답할 뿐이다. 어떤방식으로 응답할지는 객체 스스로 판단하고 결정한다.

심지어 요청에 응할지 여부도 객체 스스로 결정할 있다.

 

객체 공동체에 속한 객체들은 공동의 목표를 달성하기 위해 협력에 참여하지만 스스로의 결정과 판단에 따라 행동하는 자율적인 존재.

 

 

상태와 행동을 함께 지닌 자율적인 객체

객체를 상태(state) 행동(behavior) 함께 지닌 실체라고 정의한다.

이 말은 객체가 협력에 참여하기 위해 어떤 행동을 한다면 행동을 하는 필요한 상태도 함께 지니고 있어야 한다는 것을 의미한다.

 

객체가 협력에 참여하는 과정 속에서 스스로 판단하고 스스로 결정하는 자율적인 존재로 남기 위해서는 필요한 행동과 상태를 함께 지니고 있어야 한다.

 

객체의 자율성은 객체의 내부와 외부를 명확하게 구분하는 것으로부터 나온다.

객체의 사적인 부분은 객체 스스로 관리하고 외부에서 일체 간섭할 없도록 차단해야 하며, 객체의 외부에서는 접근이 허락된 수단을 통해서만 객체와 의사소통해야 한다.

객체는 다른 객체가 무엇(What) 수행하는지는 있지만 어떻게(how) 수행하는지에 대해서는 없다.

 

커피를 주문하는 협력 과정에 참여한 손님과 캐시어, 바리스타는 외부의 간섭을 받지 않고 스스로 생각하고 스스로 판단하는 자율적인 존재였다.

객체의 관점에서 자율성이란 자신의 상태를 직접 관리하고 상태를 기반으로 스스로 판단하고 행동할 있음을 의미한다.

객체는 행동을 위해 필요한 상태를 포함하는 동시에(바리스타는 커피 제조 방법을 기억하고 있다) 특정한 행동을 수행하는 방법을 스스로 결정할 있어야 한다.(바리스타는 자신이 알고 있는 방법에 따라 커피를 제조한다)

따라서 객체는 상태와 행위를 하나의 단위로 묶은 자율적인 존재다.

 

과거 전통적인 개발 방법은 데이터와 프로세스를 엄격하게 구분한다

이에 반해 객체지향에서는 데이터와 프로세스를 객체라는 하나의 안에 함께 묶어 놓음으로써 객체의 자율성을 보장한다.

자율적인 객체로 구성된 공동체는 유지보수가 쉽고 재사용이 용이한 시스템을 구축할 있는 가능성을 제시한다.

 

 

 

협력과 메시지

커피를 주문하기 위해 협력하는 사람들은 자신의 책임을 다하기 위해 다른 사람들에게 도움을 요청한다.

다양한 요청 방법이 있을 것이다.

 

객체지향의 세계에서는 오직 가지 의사소통 수단만이 존재한다. 이를 메시지라고 한다.

객체가 다른 객체에게 요청하는 것을 메시지를 전송한다고 다른 객체로부터 요청을 받는 것을 메시지를 수신한다고 말한다.

결과적으로 객체는 협력을 위해 다른 객체에게 메시지를 전송하고 다른 객체로부터 메시지를 수신한다.

 

 

메서드와 자율성

객체는 다른 객체와 협력하기 위해 메시지를 전송한다.

수신자는 먼저 수신된 메시지를 이해할 있는지 여부를 판단한 미리 정해진 자신만의 방법에 따라 메시지를 처리한다. 이처럼 체가 수신된 메시지를 처리하는 방법을 메서드라고 부른다.

 

객체지향 프로그래밍 언어에서 메서드는 클래스 안에 포함된 함수 또는 프로시저를 통해 구현된다.

다른 프로그래밍 언어와 객체지향 프로그래밍 언어를 구분 짓는 핵심적인 특징 하나다.

 

메시지(요청) 메서드의 분리는 객체의 협력에 참여하는 객체들 간의 자율성을 증진시킨다.

커피를 주문하는 협력과정에서 커피 제조를 요청받은 바리스타는 커피머신, 수제 커피 등등 제조 방법을 자율적으로 선택할 있다.

 

객체지향에 대입하면 커피 주문이 요청, 커피 제작하는 방법은방법은 메서드다

커피 제조를 요청한 사람은 어떻게 커피를 제조하는지 구체적인 방법을 모른다.(자율성 보장)

 

외부의 요청이 무엇인지 표현하는 메시지와 요청을 처리하기 위한 구체적인 방법인 메서드를 분리하는 것은 객체의 자율성을 높이는 핵심 메커니즘이다. 이것은 캡슐화라는 개념과도 깊이 관련돼 있다.

 

 

 

 

객체지향의 본질

객체지향이란 시스템을 상호작용하는 자율적인 객체들의 공동체로 바라보고 객체를 이용해 시스템을 분할하는 방법

자율적인 객체란 상태와 행위를 함께 지니며 스스로 자기 자신을 책임지는 객체를 의미한다.

객체는 시스템의 행위를 구현하기 위해 다른 객체와 협력한다. 각 객체는 협력 내에서 정해진 역할을 수행하며 역할은 관련된 책임의 집합이다.

객체는 다른 객체와 협력하기 위해 메시지를 전송하고, 메시지를 수신한 객체는 메시지를 처리하는 데 적합한 메서드를 자율적으로 선택한다.

 

 

객체를 지향하라

클래스가 객체지향 프로그래밍 언어의 관점에서 매우 중요한 구성요소인 것은 분명하다

하지만 객체지향의 핵심을 이루는 중심 개념이라고 말하긴 무리가 있다.

자바스크립트 같은 프로토타입 기반의 객체지향 언어에서는 클래스가 존재하지 않으며 오직 객체만이 존재한다. 프로토타입 기반의 객체지향객체지향 언어에서는 상속 역시 클래스가 아닌 객체 간의 위임 메커니즘을 기반으로 한다.

지나치게 클래스를 강조하는 프로그래밍 언어적인 관점은 객체의 캡슐화를 저해하고 클래스를 서로 강하게 결합시킨다.

 

객체지향 설계의 관점을 코드를 담는 클래스의 관점에서 메시지를 주고받는 객체의 관점으로 변환해야 한다.

중요한 것은 어떤 클래스가 필요한가 가 아니라 어떤 객체들이 어떤 메시지를 주고받으며 협력하는 가다. 클래스는 객체들의 협력 관계를 코드로 옮기는 도구에 불과하다.

 

클래스의 구조와 메서드가 아니라 객체의 역할, 책임, 협력에 집중하라. 객체지향은 객체를 지향하는 것이지 클래스를 지향하는 것이 아니다.

 

객체지향이란 실세계를 직접적이고 직관적으로 모델링할 있는 패러다임

현실 존재하는 사물을 최대한 유사하게 모방해 소프트웨어 내부로 옮겨오는 작업

이과정에서 객체란 현실 세계에 존재하는 사물에 대한 추상화라는

 

설명은 객체지향의 기반을 이루는 철학적인 개념을 설명하는 데는 적합하지만

유연하고 실용적인 관점에선 적합하지 않다.

완벽히 일치하는 경우가 거의 없기 때문이다. 예를 들어 소프트웨어 방화벽이 건물의 방화벽과  얼마나 유사하나?

 

 

 

협력하는 사람들

커피 공화국의 아침

역할, 책임, 협력 우리가 삶을 영위하기 위해 다른 사람과 접촉하는 모든 곳에 존재한다.

각각 맡은 역할을 수행하기 위해 협력하는 과정에서 책임을 다한다.

 

하나의 커피를 주문하는 과정을 예를 들어보자

손님, 캐시어, 바리스타는 각각의 역할이 있다. 손님은 커피를 주문하는 역할, 캐시어는 커피를 주문받는 역할, 바리스타는 커피를 제조하는 역할이 있다. 역할을 책임있게 수행하는 과정에서 암묵적인 협력관계가 있다.

커피 주문이라는 협력에 참여하는 모든 사람들은 커피가 정확하게 주문되고 주문된 커피가 손님에게 정확하게 전달될 있도록 맡은 역할과 책임을 다하고 있는 것이다.

 

요청과 응답으로 구성된 협력

일상에서 발생하는 대부분의 문제는 개인 혼자만의 힘으로 해결하기 버거울 정도로 복잡하다.

때문에 사람들은 스스로 해결하지 못하는 문제와 마주치면 문제 해결에 필요한 지식을 알고 있거나 서비스를 제공해줄 있는 사람에게 도움을 요청(Request)한다.

 

일반적으로 하나의 문제를 해결하기 위해 다수의 사람 혹은 역할이 필요

때문에대한 요청이 다른 사람에 대한 요청을 유발하는 것이 일반적이다.

따라서 요청은 연쇄적으로 발생한다.(협력이라 표현)

요청을 받은 사람은 주어진 책임을 다하면서 필요한 지식이나 서비스를 제공

, 다른 사람의 요청에 응답을 한다.

요청은 연쇄적으로 발생하므로 응답 역시 연쇄적으로 전달된다.

요청과 응답을 통해 다른 사람과 협력할 있는 능력은 거대하고 복잡한 문제를 해결할 있는 공동체를 형성할 있게 만든다.

협력의 성공은 특정한 역할을 맡은 개인이 얼마나 요청을 성실히 이행하는가에 달려 있다.

 

역할과 책임

사람들은 다른 사람과 협력하는 과정 속에서 특정한 역할(role) 부여받는다.

 

역할은 어떤 협력에 참여하는 특정한 사람이 협력 안에서 차지하는 책임이나 임무를 의미한다.

 

역할은 책임이라는 개념을 내포한다.

선생님 역할은 학생을 가르칠 책임이 있음을 암시한다.

경찰관 역할은 범죄자를 잡을 책임이 있음을 암시한다.

 

특정한 역할은 특정한 책임을 암시한다.

 

사람들이 협력을 위해 특정한 역할을 맡고 역할에 적합한 책임을 수행한다는 사실은 몇 가지 중요한 개념을 제시한다.

 

여러 사람이 동일한 역할을 수행할 있다.

손님 입장에서 자신이 주문한 커피를 마실 수만 있다면 어떤 캐시어가 주문을 받는지 중요치 않다.

 

역할은 대체 가능성을 의미한다.

손님 입장에서 캐시어는 대체가능하다.(substitutable)

좀 더 정확히는 두명이 동일한 역할을 수행할 수 있다면 요청자 입장에서 어떤 사람이 역할을 수행하더라도 문제가 되지 않는다.

 

책임을 수행하는 방법은 자율적으로 선택할 있다.

커피 제조를 요청받은 바리스타는 자신만의 독특한 방법으로 커피를 제조할 있다.

중요한 것은 커피를 제조하라는 동일한 요청을 받더라도 바리스타의 역할을 수행하는 사람들마다 서로 다른 방식으로 요청을 처리할 있다는 것이다.

이처럼 동일한 요청에 대해 서로 다른 방식으로 응답할 있는 능력을 다형성이라고 한다.

 

사람이 동시에 여러 역할을 수행할 있다.

캐시어와 바리스타라는 개별적인 역할을 이용해 협력 관계를 묘사했지만

사람이 캐시어와 바리스타의 역할을 동시에 수행하는 것도 가능하다.

따라서 사람이 동시에 이상의 역할을 수행하는 것도 가능하다.

 

남자가 있다. 남자의 역할은 남편, 아이의 아버지, 직장인...

 

 

 

역할, 책임, 협력

기능을 구현하기 위해 협력하는 객체들

실세계의 커피를 주문하는 과정은 객체지향의 핵심적으로 중요한 개념을 거의 대부분 포함하고 있다.

 

사람을 객체로 , 에이전트의 요청을 메시지로, 에이전트가 요청을 처리하는 방법을 메서드로

바꾸면 대부분의 설명을 객체지향이라는 문맥으로 옮겨올 있다.

 

이제 커피 주문으로 알아본 역할, 책임, 협력의 개념을 객체지향 문맥으로 옮겨 보자

 

 

역할과 책임을 수행하며 협력하는 객체들

협력의 핵심은 특정한 책임을 수행하는 역할들 간의 연쇄적인 요청과 응답을 통해 목표를 달성한다는

일상생활에서 목표는 사람들의 협력을 통해 달성되며, 목표는 작은 책임으로 분할되고 책임을 수행할 있는 적절한 역할을 가진 사람에 의해 수행된다.

협력에 참여하는 개인은 책임을 수행하기 위해 다른 사람에게 도움을 요청하기도 하며, 이를 통해 연쇄적인 요청과 응답으로 구성되는 협력 관계가 완성된다.

객체도 이런 인간 세계와 유사하다.

 

애플리케이션의 기능은 작은 책임으로 분할되고 책임은 적절한 역할을 수행할 있는 객체에 의해 수행된다.

객체는 자신의 책임을 수행하는 도중 다른 객체에게 도움을 요청하기도 한다.

시스템은 역할과 책임을 수행하는 객체로 분할되고 시스템의 기능은 객체 간에 연쇄적인 요청과 응답의 흐름으로 구성된 협력으로 구현된다.

 

객체지향 설계는 적절한 객체에게 적절한 책임을 할당하는 것에서 시작된다.

책임이 불분명한 객체는 애플리케이션의 미래 역시 불분명하게 만든다.

 

역할은 관련성 높은 책임의 집합이다.

 

역할은 유연하고 재사용 가능한 협력 관계를 구축하는데 중요한 설계 요소다.

대체 가능한 역할과 책임 객체지향 패러다임의 중요한 기반을 제공하는 다형성과도 깊이 연관돼있다.

 

 

+ Recent posts