군만두의 IT 공부 일지

[스터디5] 01. 협력하는 객체들의 공동체, 이상한 나라의 객체 본문

프로그래밍/객체지향

[스터디5] 01. 협력하는 객체들의 공동체, 이상한 나라의 객체

mandus 2025. 2. 20. 20:57

목차

     

     

     

     

     

      제목: 객체지향의 사실과 오해

      저자: 조영호

      출판사: 위키북스

      가격: 20,000원

     

     

    역할, 책임, 협력 관점에서 본 객체지향

     

     

     

     

     

     

    지금까지 진행한 방식과 동일하게 블로그에 객체지향 책을 학습한 내용을 정리하려고 한다. 중요한 부분 위주로 정리했는데, 예시를 들어 설명하는 부분이 더 많았기 때문에 정리하기가 쉽지 않았다. 깃허브 이슈에는 책을 읽으며 궁금한 점을 작성 후 의논할 것인데, 이번 주차에 대한 궁금한 점은 아직 없었다.

    01. 협력하는 객체들의 공동체

    보편적으로 "객체지향이란 실세계를 직접적이고 직관적으로 모델링할 수 있는 패러다임"이고, "객체지향 소프트웨어는 실세계의 투영"이며, "객체란 현실 세계에 존재하는 사물에 대한 추상화"라고 설명한다.

     

    "실세계의 모방"이라는 객체지향의 개념은 실무적인 관점에서는 부적합하지만, 객체지향이라는 용어에 담긴 기본 사상을 이해하고 학습하는 데는 효과적이다.

    • 객체지향의 목표: 실세계를 모방하는 것이 아니라 새로운 세계를 창조하는 것.
    • 실용적인 관점: 객체지향 분석, 설계는 협력, 역할, 책임을 중심으로 이루어진다.

    협력하는 사람들

    책에서는 손님, 캐시어, 바리스타 사이의 암묵적인 협력 관계와 역할, 책임에 대한 실생활 예시를 설명한다.

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

    • 문제 해결에 도움을 줄 수 있는 사람에게 도움을 요청(request)하고, 요청을 받은 사람은 다른 사람의 요청에 응답(respons)한다.
    • 요청과 응답은 연쇄적으로 발생하고 전달된다.
    • 요청과 응답을 통해 다른 사람과 협력(collaboration)할 수 있는 능력은 거대하고 복잡한 능력을 해결할 수 있는 공동체를 형성한다.

    역할과 책임

    • 사람들은 다른 사람과 협력하는 과정 속에서 특정한 역할(role)을 부여받는다.
    • 역할을 맡은 사람은 역할에 적합한 책임(responsibility)을 수행한다.
    - 여러 사람이 동일한 역할을 수행할 수 있다.
    - 역할은 대체 가능성을 의미한다.
    - 책임을 수행하는 방법은 자율적으로 선택할 수 있다.
    - 한 사람이 동시에 여러 역할을 수행할 수 있다.

    역할, 책임, 협력

    • 시스템은 역할과 책임을 수행하는 객체로 분할된다.
    • 시스템의 기능은 객체 간의 연쇄적인 요청과 응답의 흐름으로 구성된 협력으로 구현된다.
    • 역할은 유연하고 재사용한 협력 관계를 구축하는 데 중요한 설계 요소다.
    • 대체 가능한 역할과 책임은 다형성과도 연관되어 있다.
    객체의 역할
    - 여러 객체가 동일한 역할을 수행할 수 있다.
    - 역할은 대체 가능성을 의미한다.
    - 각 객체는 책임을 수행하는 방법을 자율적으로 선택할 수 있다.
    - 하나의 객체가 동시에 여러 역할을 수행할 수 있다.

    협력 속에 사는 객체

    객체는 애플리케이션의 기능을 구현하기 위해 존재한다. 일반적으로 객체는 다른 객체와의 협력을 통해 기능을 구현한다.

     

    협력 공동체의 일원으로서 객체는 두 가지 덕목을 갖추고 균형을 유지해야 한다.

    1. 객체는 충분히 '협력적'이어야 한다.
      • 객체는 다른 객체의 요청과 다른 객체에게 보내는 요청에 있어 열려있어야 한다.
      • 어떤 방식으로 응답할지는 객체 스스로 판단하고 결정한다.
      • 요청에 응할지 여부도 객체 스스로 결정할 수 있다.
    2. 객체는 충분히 '자율적'이어야 한다.
      • 객체는 자기 스스로의 원칙에 따라 자신의 행동을 스스로 결정하고 행동해야 한다.

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

    • 흔히 객체를 상태(state)행동(behavior)을 지닌 실체라고 정의한다.
      • 객체가 협력에 참여하기 위해 어떤 행동을 해야 한다면 그 행동을 하는 데 필요한 상태도 함께 지니고 있어야 한다.
    • 객체의 자율성은 객체의 내부와 외부를 명확히 구분하는 것에서 나온다.
      • 객체는 다른 객체가 무엇(what)을 수행하는지는 알 수 있지만, 어떻게(how) 수행하는지에 대해서는 알 수 없다.
      • 객체의 관점에서 자율성이란 자신의 상태를 직접 관리하고 상태를 기반으로 스스로 판단하고 행동할 수 있음을 의미한다.

    협력과 메시지

    • 메시지: 객체지향의 세계에 존재하는 오직 한가지의 의사소통 수단
    • 객체는 협력을 위해 다른 객체에게 메시지를 전송하고, 다른 객체로부터 메시지를 수신한다.
      • 송신자(sender): 메시지를 전송하는 객체
      • 수신자(receiver): 메시지를 수신하는 객체

    메서드와 자율성

    • 객체는 다른 객체와 협력하기 위해 메시지를 전송한다.
    • 메서드(method): 객체가 수신된 메시지를 처리하는 방법.
      • 객체지향 프로그래밍 언어에서 메서드는 클래스 안에 포함된 함수 또는 프로시저를 통해 구현된다.
      • 메시지를 수신한 객체가 실행 시간에 메서드를 선택할 수 있다.

    외부의 요청이 무엇인지를 표현하는 메시지와 요청을 처리하기 위한 구체적인 방법인 메서드를 분리하는 것은 객체의 자율성을 높이며, 캡슐화(encapsulation)와 깊이 관련되어 있다.

    객체지향의 본질

    - 객체지향이란 시스템을 상호작용하는 자율적인 객체들의 공동체로 바라보고 객체를 이용해 시스템을 분할하는 방법이다.
    - 자율적인 객체란 상태행위를 함께 지니며 스스로 자기 자신을 책임지는 객체를 의미한다.
    - 객체는 시스템의 행위를 구현하기 위해 다른 객체와 협력한다. 각 객체는 협력 내에서 정해진 역할을 수행하며 역할은 관련된 책임의 집합이다.
    - 객체는 다른 객체와 협력하기 위해 메시지를 전송하고, 메시지를 수신한 객체는 메시지를 처리하는 데 적합한 메서드를 자율적으로 선택한다.

    객체를 지향하라

    널리 알려진 미신과 달리 객체지향의 핵심은 클래스가 아니다. 핵심은 적절한 책임을 수행하는 역할 간의 유연하고 견고한 협력 관계를 구축하는 것이다. 클래스는 협력에 참여하는 객체를 만드는 데 필요한 구현 메커니즘일 뿐이다.

     

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

    02. 이상한 나라의 객체

    객체지향과 인지 능력

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

     

    하지만 객체지향 패러다임의 목적은 현실 세계를 모방하는 것이 아니라, 현실 세계를 기반으로 새로운 세계를 창조하기 때문에 현실 객체와는 다른 모습이다.

    객체, 그리고 이상한 나라

    책에서는 '이상한 나라의 앨리스' 에서 앨리스가 정원으로 가는 길을 가로막고 있는 작은 문을 통과하기 위해 자신의 키를 줄이거나 늘리는 상태 변화에 대해서 설명한다.

     

    이때 앨리스의 키를 변화시키는 것은 앨리스의 행동이다. 여기서 어떤 행동의 성공 여부는 이전에 어떤 행동들이 발생했는지에 영향을 받는다는 사실로부터 행동 간의 순서가 중요하다는 것을 알 수 있다.

     

    그리고 행동에 의해 상태가 변경되더라도 객체가 객체라는 사실은 변하지 않는다. 상태 변경과 무관하게 유일한 존재로 식별 가능하다.

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

    • 하나의 개별적인 실체로 식별 가능한 물리적인 또는 개념적인 사물은 어떤 것이라도 객체가 될 수 있다.
    • 객체의 다양한 특성을 효과적으로 설명하기 위해 객체를 상태(state), 행동(behavior), 식별자(identity)를 지닌 실체로 본다.
    객체란 식별 가능한 개체 또는 사물이다. 객체는 자동차처럼 만질 수 있는 구체적인 사물일 수도 있고, 시간처럼 추상적인 개념일 수도 있다. 객체는 구별 가능한 식별자, 특징적인 행동, 변경 가능한 상태를 가진다. 소프트웨어 안에서 객체는 저장딘 상태와 실행 가능한 코드를 통해 구현된다.

    상태

    왜 상태가 필요한가
    • 상태를 이용하면 과거의 모든 행동 이력을 설명하지 않고도 행동의 결과를 쉽게 예측하고 설명할 수 있다.
    • 상태를 이용하면 과거에 얽매이지 않고 현재를 기반으로 객체의 행동 방식을 이해할 수 있다.
    • 상태는 근본적으로 세상의 복잡성을 완화하고 인지 부조화를 줄이기 위해 필요하다.
    상태와 프로퍼티
    • 객체의 상태는 단순한 값과 객체의 객체의 조합으로 표현될 수 있다.
    • 객체의 프로퍼티(property):객체의 상태를 구성하는 모든 특징
    • 일반적으로 프로퍼티는 변경되지 않고 고정되기 때문에 '정적'이지만, 프로퍼티 값(property value)은 시간이 흐름에 따라 변경되기 때문에 '동적'이다.
    • 링크(link): 객체와 객체 사이의 의미 있는 연결
    • 객체와 객체 사이에는 링크가 존재해야만 요청을 보내고 받을 수 있다.
    • 속성(attribute): 객체를 구성하는 단순한 값

    객체의 프로퍼티는 단순한 값인 속성과 다른 객체를 가리키는 링크라는 두 가지 종류의 조합으로 표현할 수 있다.

    상태는 특정 시점에 객체가 가지고 잇는 정보의 집합으로 객체의 구조적 특징을 표현한다. 객체의 상태는 객체에 존재하는 정적인 프로퍼티와 동적인 프로퍼티 값으로 구성된다. 객체의 프로퍼티는 단순한 값과 다른 객체를 참조하는 링크로 구분할 수 있다.

    행동

    상태와 행동
    • 객체가 취하는 행동은 객체 자신의 상태를 변경시킨다.
    • 객체의 행동에 의해 객체의 상태가 변경된다는 것은 행동이 부수 효과(side effect)를 초래한다는 것이다.
    • 객체의 행동은 객체의 상태를 변경시키지만, 행동의 결과는 객체의 상태에 의존적이다.
    상태와 행동 사이의 관계
    - 객체의 행동은 상태에 영향을 받는다.
    - 객체의 행동은 상태를 변경시킨다.
    행동을 서술하는 관점
    - 상호작용이 현재의 상태에 어떤 방식으로 의존하는가
    - 상호작용이 어떻게 현재의 상태를 변경시키는가

     

    협력과 행동
    • 객체는 자신에게 주어진 책임을 완수하기 위해 다른 객체를 이용하고 다른 객체에게 서비스를 제공한다.
    • 객체는 다른 객체와 적극적으로 상호작용하며 '협력하는 객체들의 공동체'에 참여하기 위해 다른 객체에게 요청을 보낸다.
    • 요청을 수신한 객체는 요청을 처리하기 위해 적절한 방법에 따라 행동한다.
    • 객체는 협력에 참여하는 과정에서 자기 자신의 상태뿐만 아니라 다른 객체의 상태 변경을 유발할 수 있다.
    객체의 행동을 서술하는 관점
    - 객체 자신의 상태 변경
    - 행동 내에서 협력하는 다른 객체에 대한 메시지 전송
    행동이란 외부의 요청 또는 수신된 메시지에 응답하기 위해 동작하고 반응하는 활동이다. 행동의 결과로 객체는 자신의 상태를 변경하거나 다른 객체에게 메시지를 전달할 수 있다. 객체는 행동을 통해 다른 객체와의 협력에 참여하므로 행동은 외부에 가시적이어야 한다.

     

    상태 캡슐화
    • 캡슐화: 메시지 송신자는 메시지 수신자의 상태 변경에 대해서 알 수 없는 것
    • 객체는 상태를 캡슐 안에 감춰둔 채 외부로 노출하지 않는다.
    • 객체가 외부에 노출하는 것은 행동뿐이며, 외부에서 객체에 접근할 수 있는 유일한 방법 역시 행동뿐이다.
    • 객체의 행동을 유발하는 것은 외부로부터 전달된 메시지지만, 객체의 상태를 변경할지 여부는 객체 스스로 결정한다.
    • 상태를 외부에 노출시키지 않고 행동을 경계로 캡슐화하는 것은 객체의 자율성을 높이고, 협력을 단순하고 유연하게 만든다.

    식별자

    • 식별자: 객체를 식별 가능하게 하기 위해 객체 안에 존재하는 서로 구별할 수 있는 특정한 프로퍼티
      • 모든 객체는 식별자를 가지며 식별자를 이용해 객체를 구별할 수 있다.
      • 값과 객체의 가장 큰 차이점은 은 식별자를 가지지 않지만, 객체는 식별자를 가진다는 점이다.
    • 값(value): 숫자, 문자열, 날짜, 시간, 금액 등과 같이 변하지 않는 양을 모델링한다.
      • 값의 상태는 변하지 않기 때문에 불변 상태(immutable state)를 가진다고 한다.
      • 값이 같은지 여부는 상태가 같은지를 이용해 판단하는 성질을 동등성(equality)이라고 한다.
    • 객체는 시간에 따라 변경되는 상태를 포함하며, 행동을 통해 상태를 변경하기 때문에 가변 상태(mutable state)를 가진다.
    • 두 객체의 상태와 무관하게 식별자를 기반으로 두 객체를 같은지를 판단할 수 있는 성질을 동일성(identical)이라고 한다.
    식별자란 어떤 객체를 다른 객체와 구분하는 데 사용하는 객체의 프로퍼티다. 값은 식별자를 가지지 않기 때문에 상태를 이용한 동등성 검사를 통해 두 인스턴스를 비교해야 한다. 객체는 상태가 변경될 수 있기 때문에 식별자를 이용한 동일성 검사를 통해 두 인스턴스를 비교할 수 있다.
    • 값과 객체의 차이로 인한 오해의 소지를 줄이기 위해서 별도의 용어를 사용하기도 한다.
      • 참조 객체(reference object), 엔티티(entity)는 식별자를 지닌 전통적인 의미의 객체를 가리킨다.
      • 값 객체(value object)는 식별자를 가지지 않는 값을 가리킨다.
    - 객체는 상태를 가지며 상태는 변경 가능하다.
    - 객체의 상태를 변경시키는 것은 객체의 행동이다.
       - 행동의 결과는 상태에 의존적이며 상태를 이용해 서술할 수 있다.
       - 행동의 순서가 실행 결과에 영향을 미친다.
    - 객체는 어떤 상태에 있더라도 유일하게 식별 가능하다.

    기계로서의 객체

    • 쿼리(query): 객체의 상태를 조회하는 작업
    • 명령(command): 객체의 상태를 변경하는 작업
    • 객체가 외부에 제공하는 행동의 대부분은 쿼리와 명령으로 구성된다.

    책에서는 마이어가 제시한 기계 은유를 이용해 객체를 표현한다. 사용자는 객체가 제공하는 명령 버튼과 쿼리 버튼으로 구성된 인터페이스를 통해서만 객체에 접근할 수 있다. 객체 기계가 제공하는 버튼을 통해서만 사태에 접근할 수 있다는 점은 객체의 캡슐화를 의미한다.

     

    객체를 기계로서 바라보는 관점은 상태, 행동, 식별자에 대한 시각적인 이미지를 제공하고, 캡슐화와 메시지를 통한 협력 관계를 설명한다.

    행동이 상태를 결정한다

    상태를 중심으로 객체를 바라보는 것은 설계에 나쁜 영향을 끼친다.

    1. 상태를 먼저 결정할 경우 캡슐화가 저해된다.
    2. 객체를 협력자가 아닌 고립된 섬으로 만든다.
    3. 객체의 재사용성이 저하된다.

    협력 안에서 객체의 행동은 결국 객체가 협력에 참여하면서 완수해야 하는 책임을 의미한다. 객체를 상태가 아닌 행동에 초점을 중심으로 바라보아야 한다.

    은유와 객체

    • 객체지향의 세계와 현실 세계 사이의 관계를 정확하게 설명하는 단어는 은유(metaphor)다.
      • 은유란 실제로는 적용되지 않는 한 가지 개념을 이용해 다른 개념을 서술하는 대화의 한 형태다.
      • 은유는 표현적 차이(representational gap) 또는 의미적 차이(semantic gap)라는 논점과 관련성이 깊다.
      • 차이란 소프트웨어에 대해 사람들이 새각하는 모습과 실제 소프트웨어의 표현 사이의 차이를 의미한다.

    소프트웨어 객체에 대한 현실 객체의 은유를 효과적으로 사용할 경우 표현적 차이를 줄일 수 있으며, 이해하기 쉽고 유지보수가 용이한 소프트웨어를 만들 수 있다.

    참고자료

    1) 5th-book-club, "The-Essence-Of-Object-Orientation", https://github.com/5th-book-club/The-Essence-Of-Object-Orientation

    2) de-vook, "The-Essence-of-Object-Orientation", https://github.com/de-vook/The-Essence-of-Object-Orientation

    이 글은 『객체지향의 사실과 오해』 책을 학습한 내용을 정리한 것입니다.
    Comments