ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 『객체지향의 사실과 오해』를 읽고. 메시지, 협력만 기억해도 성공!
    📝 기록/독서 기록 2022. 9. 16. 17:33

    오늘은 2주에 걸쳐 총 2회독을 한 『객체지향의 사실과 오해』 (조영호 저)에 대해서 정리해보려고 한다. 이번에도 역시나 볼펜으로 중요하다고 생각되는 부분을 줄 치면서 읽었는데, 1회독에는 빨간 펜으로 핵심이라고 생각되는 문장들을 줄 쳤다. 2회독은 1회독 때 줄 쳐놓은 것을 위주로 다시금 제대로 읽고, 1회독 때 놓쳤던 중요한 내용들을 파란 펜으로 줄 치면서 읽었다. 그래서 내가 줄 친 내용들 중 중요한 키워드를 두고두고 보기 위해 블로그에 정리해본다.


    객체지향으로 향하는 Steps

    1. 클래스가 아니라 객체를 바라보는 것에서부터 시작한다.
    2. 객체를 독립적인 존재가 아니라 기능을 구현하기 위해 협력하는 공동체로 바라볼 것. 
    3. 걸음을 내디딜 수 있는지 여부는 협력에 참여하는 객체들에게 얼마나 적절한 역할과 책임을 부여할 수 있느냐에 달려있다.
    4. 앞서 설명한 개념들을 프로그래밍 언어라는 틀에 흐트러짐없이 담아낼 수 있는 기술을 익히는 것이다.

    역할, 책임, 협력

    ✅ 객체지향에서 가장 중요한 개념 3가지: 역할, 책임, 협력!
    ✅ 객체지향 패러다임의 핵심: 자율적인 객체들의 협력!

    객체지향의 목표는 실세계를 모방하는 것이 아니다: 실세계의 모방이라는 개념은 객체지향의 기반을 이루는 철학적인 개념을 설명하는 데는 적합하지만 유연하고 실용적인 관점에서 객체지향 분석, 설계를 설명하기에는 적합하지 않다. 다만 실세계에 대한 비유가 객체지향의 다양한 측면을 이해하고 학습하는 데 매우 효과적이기에 이렇게 비유를 하곤 하는데, 사실은 새로운 세계를 창조하는 것이다. 소프트웨어 개발자의 역할은 단순히 실세계를 소프트웨어 안으로 옮겨 담는 것이 아니라 고객과 사용자를 만족시킬 수 있는 신세계를 창조하는 것이다.

    객체는 결코 독립적이지 않고, 협력한다: 애플리케이션의 기능은 더 작은 책임으로 분할되고 책임은 적절한 역할을 수행할 수 있는 객체에 의해 수행된다. 즉, 시스템은 역할과 책임을 수행하는 객체로 분할되고 시스템의 기능은 객체 간의 연쇄적인 요청과 응답의 흐름으로 구성된 협력으로 구현된다. 협력의 핵심은 특정한 책임을 수행하는 역할들 간의 연쇄적인 요청과 응답을 통해 목표를 달성한다는 것이다.

    역할은 관련성 높은 책임의 집합이다: 역할은 유연하고 재사용 가능한 협력 관계를 구축하는 데 중요한 설계 요소다. 특정한 역할은 특정한 책임을 암시한다. 대체 가능한 역할과 책임은 객체지향 패러다임의 중요한 기반을 제공하는 다형성과도 깊이 연관돼 있다.

    요청과 응답 그리고 메시지

    객체지향의 세계에서는 '메시지'라는 오직 한 가지 의사소통 수단만이 존재한다: 한 객체가 다른 객체에게 요청하는 것을 '메시지를 전송한다'고 말하고, 다른 객체로부터 요청을 받는 것을 '메시지를 수신한다'고 말한다. 이때 메시지를 전송하는 객체를 송신자(sender)라고 부르고 메시지를 수신하는 객체를 수신자(receiver)라고 부른다.

    수신된 메시지는 메서드로 처리한다: 수신자는 먼저 수신된 메시지(요청)를 이해할 수 있는지 여부를 판단한 후 미리 정해진 자신만의 방법에 따라 메시지를 처리한다. 객체가 수신된 메시지를 처리하는 방법을 메서드(method)라고 부르는데, 메서드란 특정한 로직을 처리하는 함수를 의미한다.

    클래스는 객체지향의 핵심이 아니다: 중요한 것은 어떤 클래스가 필요한가가 아니라 어떤 객체들이 어떤 메시지를 주고받으며 협력하는가다. 핵심은 적절한 책임을 수행하는 역할 간의 유연하고 견고한 협력 관계를 구축하는 것이다. 클래스는 그 협력에 참여하는 객체를 만드는 데 필요한 구현 메커니즘일 뿐이다. 클래스의 구조와 메서드가 아니라 객체의 역할, 책임, 협력에 집중하라.

    상태와 행동 그리고 자율성

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

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

    - 객체는 자율적이어야 한다: 객체 공동체에 속한 객체들은 공동의 목표를 달성하기 위해 협력에 참여하지만 스스로의 결정과 판단에 따라 행동하는 자율적인 존재여야 한다. 객체는 다른 객체의 명령에 복종하는 것이 아니라 요청에 응답할 뿐이다. 어떤 방식으로 응답할지는 객체 스스로 판단하고 결정한다. 객체지향의 기본 사상은 상태와 상태를 조작하기 위한 행동을 하나의 단위로 묶는 것이라는 점을 기억해야 한다. 객체는 스스로의 행동에 의해서만 상태가 변경되는 것을 보장함으로써 객체의 자율성을 유지한다.

    캡슐화

    - 캡슐화란 객체의 자율성을 보존하기 위해 구현을 외부로부터 감추는 것을 말한다: 캡슐화는 '상태와 행위의 캡슐화'와 '사적인 비밀의 캡슐화' 이렇게 두 가지로 사용된다. '상태와 행위의 캡슐화'는 행동은 최대한 드러내고 상태는 최대한 숨기는 것이다. '사적인 비밀의 캡슐화'는 굳이 외부에까지 공개되지 않아도 되는, 사적인 내용들을 숨기는 것이며 이를 '정보 은닉'이라고도 한다. 행동끼리 모아 응집성 있는 상태들이 뭉쳐져 있는 것 또한 캡슐화에 해당한다.

    인터페이스

    - 인터페이스는 '외부에서 접근 가능한 공개된 인터페이스'와 '내부에서만 접근할 수 있는 감춰진 인터페이스'로 구분된다: 인터페이스란, 어떤 두 사물이 마주치는 경계 지점에서 서로 상호작용할 수 있게 이어주는 방법이나 장치를 말한다. 공용 인터페이스는 내부에서만 접근 가능한 사적인 인터페이스와 구분하기 위해 외부에 공개된 인터페이스를 말한다.

    - 인터페이스의 세가지 특징: 
    1. 인터페이스의 사용법을 익히기만 하면 내부 구조나 동작 방식을 몰라도 쉽게 대상을 조작하거나 의사를 전달할 수 있다.
    2. 인터페이스 자체는 변경하지 않고 단순히 내부 구성이나 작동 방식만을 변경하는 것은 인터페이스의 사용자에게 어떤 영향도 미치지 않는다.
    3. 대상이 변경되더라도 동일한 인터페이스를 제공하기만 하면 아무런 문제 없이 상호작용할 수 있다.

    - 공용 인터페이스건 사적인 인터페이스건 상관없이 모든 인터페이스는 메시지 전송을 통해서만 접근할 수 있다: 단지 메시지 송신자가 객체인지 아니면 객체 자신인지만 다를 뿐이다.

    추상화

    - 추상화는 실제의 사물에서 자신이 원하는 특성만 취하고 필요 없는 부분을 추려 핵심만 표현하는 행위를 말한다: 추상화(abstraction)의 목적은 복잡성을 이해하기 쉬운 수준으로 단순화하는 것이라는 점을 기억해야 한다. 

    일반화/특수화 관계

    - 일반화 객체는 특수화 객체를 포괄하는 좀 더 일반적인 개념이다. 특수화 객체는 일반화 객체보다 좀 더 특화된 행동을 하는 특수한 개념이다. 이 두 개념 사이의 관계를 일반화/특수화(generalization/specialization) 관계라고 한다.

    다형성

    - 동일한 요청에 대해 서로 다른 방식으로 응답하는 것을 다형성(polymorphism)이라고 한다: 객체는 책임을 수행하는 방법을 자율적으로 선택할 수 있다. 이때 다형성이란 서로 다른 유형의 객체가 동일한 메시지에 대해 서로 다르게 반응하는 것을 의미한다. 좀 더 구체적으로 말해 서로 다른 타입에 속하는 객체들이 동일한 메시지를 수신할 경우 서로 다른 메서드를 이용해 메시지를 처리할 수 있는 메커니즘을 가리킨다.

    - 다형성은 객체들의 대체 가능성을 이용해 설계를 유연하고 재사용 가능하게 만든다: 다형성을 사용하면 송신자가 수신자의 종류를 모르더라도 메시지를 전송할 수 있다. 즉, 다형성은 수신자의 종류를 캡슐화한다. 객체지향 용어를 이용해 표현하자면 다형성은 송신자와 수신자 간의 객체 타입에 대한 결합도를 메시지에 대한 결합도로 낮춤으로써 달성한다.


    이 책은 기본적으로 핵심 내용을 다양한 예제를 나열하며 같은 말을 계속 반복한다. 결국 객체지향에서 가장 중요한 것은 메시지 그리고 그 메시지를 받아 행동하는 객체들의 협력 관계이다. 이 두 가지만 기억한다면 이 책을 다 봤다고 과언이 아닌 수준이다. 앞으로는 각 객체마다 어떤 메시지를 보낼지에 대해서 고민하고, 테스트 코드를 작성해가면서 올바른 협력 관계를 구축한 객체들을 만들 수 있게 훈련해보자.