[임시] 객체지향의 사실과 오해 (작성중)

Taurine·2022년 1월 23일
0
post-thumbnail

자기만의 정의

  • "객체지향이란 무엇일까요? 물론 이 질문에 정답이란 존재하지 않습니다. 중요한 것은 여러분이 이질문에 대한 자신만의 견해를 가지고 있느냐는 것입니다. 안타깝게도 대부분의 사람들은 여전히 객체지향이란 무엇인가에 대해 자신있게 대답하지 못하는 것 같습니다. 실제로 상속이 무엇인지는 대답할 수 있지만 일반화가 무엇인지에 대해서는 대답하지 못하는 개발자분들이 꽤 많습니다. 객체지향이 말 그대로 객체를 지향한다는 사실을 잘 알고 있으면서도 많은 분들이 여전히 클래스나 상속을 중심으로 객체지향을 바라보고 있습니다."

개발책 읽는 이유

  • "여러분이 객체지향 프로그래밍에 대한 어느정도의 지식을 가지고 계시다면 글과 그림의 의미를 여러분의 경험과 쉽게 연결하실 수 있을 겁니다... 실제로 코드를 작성한 경험이 많으면 많을 수록 객체지향 프로그래밍 언어에 대한 지식이 많으면 많을 수록 책의 행간에 숨겨져 있는 의미를 좀 더 깊이 있게 이해할 수 있을 겁니다."
  • "기술적인 지식을 비기술적인 이야기로 풀어내는 것은 정말로 즐겁고도 흥분되는 도전이었습니다. 하지만 책을 쓰는 내내 기술적인 문맥에 적절한 이야기를 만들어내야 한다는 압박감에 시달렸습니다."
  • "책을 덮은 후 여러분들이 지금까지 해왔던 방식을 뒤돌아보면서 깊은 사색에 잠길 수만 있다면 이 책은 그 목적을 다한 것이라고 생각합니다."
  • "이 책의 목표는 페이지를 한장 한장 넘길 때마다 프로그래밍을 했던 기억을 떠올리며 그게 이런 의미였구나 그래서 그 언어가 그런 방식으로 설계됐구나라는 생각을 하도록 만드는 것입니다."

모델링

  • "객체지향이란 실세계를 직접적이고 직관적으로 모델링할 수 있는 패러다임"
  • "객체지향 프로그래밍이란 현실속에 존재하는 사물을 최대한 유사하게 모방해 소프트웨어 내부로 옮겨오는 작업이기 때문에 그 결과물인 객체지향 소프트웨어는 실세계의 투영이며 객체란 현실 세계에 존재하는 사물에 대한 추상화라는 것이다."
  • "객체지향의 목표는 실세계를 모방하는 것이 아니다. 오히려 새로운 세계를 창조하는 것이다. 소프트웨어 개발자의 역할은 단순히 실세계를 소프트웨어 안으로 옮겨담는 것이 아니라 고객과 사용자를 만족시킬 수 있는 신세계를 창조하는 것이다."
  • "추상화랑 실제의 사물에서 자신이 원하는 특성만 취하고 필요없는 부분을 추려 핵심만 표현하는 행위를 말한다."
  • "일단 컴퓨터를 조작하는 것이 추상화를 구축하고, 조작하고, 추론하는 것에 관한 모든 것이라는 것을 깨닫고 나면 훌륭한 컴퓨터 프로그램을 작성하기 위한 중요한 전제조건은 추상화를 정확하게 다루는 능력이라는 것이 명확해진다." -키스 데블린
  • "지하철 노선도 디자인에서 가장 중요한 것은 얼마나 사실적으로 지형을 묘사했냐가 아니라 역과 역 사이의 연결성을 얼마나 직관적으로 표현했느냐다. 그러나 초기의 지하철 노선도는 이동이라는 본래의 목적과는 무관한 사실적인 지형 정보를 혼합함으로써 역 사이의 연결성이라는 중요한 정보를 파악하기 힘들게 만드는 잘못을 범하고 말았다... 해리 벡이 창조한 지하철 노선도의 핵심은 지도가 당연히 가져야 한다고 생각되는 정확성을 버리고 그 목적에 집중한 결과다... 이 지도는 상식에 근거한 것입니다. 지하철을 갈아탈 때 지형 때문에 골치 하플 필요가 있을까요? 지형은 중요한 것이 아닙니다. 중요한 것은 연결, 즉 열차를 갈아타는 것입니다."
  • "객체지향 패러다임은 지식을 추상화하고 추상화한 지식을 객체안에 캡슐화함으로써 실세계 문제에 내재된 복잡성을 관리하려고 한다. 객체를 발견하고 창조하는 것은 지식과 행동을 구조화하는 문제다. -레베카 워프스브룩"

인간 인식 특성

  • "현실은 복잡하며 예측 불가능한 혼돈의 덩어리다... 현실에 존재하는 다양한 현상 및 사물과 상호작용하기 위해서는 우선 현실을 이해해야 한다. 문제는 복잡성의 총체인 현실이라는 괴물을 그대로 수용하기에는 인간이 지니고 있는 인지능력과 저장공간이 너무나도 보잘것 없다는 점이다. 따라서 사람들은 본능적으로 이해하기 쉽고 예측 간으한 수준으로 현실을 분해하고 단순화하는 전략을 따른다... 따라서 진정한 의미의 추상화란 현실에서 출발하되 불필요한 부분을 도려내가면서 사물의 놀라운 본질을 드러나게 하는 과정이라고 할 수 있다. 추상화의 목적은 불필요한 부분을 무시함으로써 현실에 존재하는 복잡성을 극복하는 것이다. 추상화는 복잡한 현실을 단순화하기 위해 사용하는 인간의 가장 기본적인 인지수단이라고 할 수 있다."
  • "공통점을 기반으로 객체들을 묶기 위한 그릇을 개념이라고 한다. 개념이란 일반적으로 우리가 인식하고 있는 다양한 사물이나 객체에 적용할 수 있는 아이디어나 관념을 뜻한다. 우리는 주변에 존재하는 다양한 사물들에게 특정한 개념을 적용하는데 익숙하다. 길거리를 빠른 속도로 누비는 교통수단에 대해서는 자동차라는 개념을 적용한다. 하늘을 나는 교통수단을 지칭하는 개념은 비행기다..."
  • "개념은 세상의 객체들을 거르는데 사용하는 정신적인 렌즈를 제공한다. 이 렌즈를 통해 세상을 바라보면 수백 수천개의 다양한 객체가 존재하는 복잡한 세상을 몇개의 개념만으로 단순화할 수 있다. 개념은 객체를 분류할 수 있는 틀을 제공한다... 주변의 복잡한 객체들은 단지 몇가지 개념의 인스턴스일 뿐이다."
  • "사람은 태어난지 얼마 안된 시기부터 뚜렷한 경계를 가지고 함께 행동하는 문제를 하나의 개념으로 인지한다는 사실을 알 수 있다. 아기들은 물체가 여러부분으로 구성돼 있더라도 함께 움직일 경우 그 물체를 하나의 유기적인 단위로 인식한다. 아기들 역시 뚜렷한 경계를 가진 객체들의 집합으로 세상을 바라보는 것이다."

추상화 방식

  • "복잡성을 다루기 위해 추상화는 두가지 차원에서 이뤄진다. 1. 구체적인 사물들 간의 공통점은 취하고 차이점은 버리는 일반화를 통해 단순하게 만드는 것이다. 2. 중요한 부분을 강조하기 위해 불필요한 세부 사항을 제거함으로써 단순하게 만드는 것이다. => 모든 경우에 추상화의 목적은 복잡성을 이해하기 쉬운 수준으로 단순화하는 것이라는 점을 기억하라."

기억하기 편함

  • "객체지향 설계자로서 우리의 목적은 현실을 모방하는 것이 아니다. 단지 이상한 나라를 창조하기만 하면 된다. 현실을 닮아야 한다는 어떤 제약이나 구속도 없다. 여러분이 창조한 객체의 특성을 상기시킬 수 있다면 현실 속의 객체의 일므을 이용해 객체를 묘사하라. 그렇지 않다면 깔끔하게 혈실을 무시하고 자유롭게 여러분만의 새로운 세계를 창조하기 바란다. 앨리스를 매혹시킨 이상한 나라가 그런것처럼 말이다."
  • "소프트웨어 객체에 대한 현실객체의 은유를 효과적으로 사용할 경우 표현적 차이를 줄일 수 있으며 이해하기 쉽고 유지보수가 용이한 소프트웨어를 만들 수 있다. 바로 이러한 이유로 모든 객체지향 지침서에서는 현실 세계의 도메인에서 사용되는 이름을 객체에게 부여하라고 가이드하는 것이다."
  • "분류는 객체지향의 가장 중요한 개념중 하나다. 어떤 객체를 어떤 개념으로 분류할지가 객체지향의 품질을 결정한다. 객체를 적절한 개념에 따라 분류하지 못한 애플리케이션은 유지보수가 어렵고 변화에 쉽게 대처하지 못한다... 더 중요한 것은 적절한 분류체계는 애플리케이션을 다루는 개발자의 머릿속에 객체를 쉽게 찾고 조작할 수 있는 정신적인 지도를 제공한다는 것이다. 객체는 소중하다. 따라서 소중한 객체를 안전하고 적절한 장소에 보관할 수 있도록 여러분의 인지능력을 발휘해 최대한 직관적으로 분류하라."
  • "많은 사람들이 객체지향을 직관적이고 이해하기 쉬운 패러다임이라고 말하는 이유는 객체지향이 세상을 자율적이고 독립적인 객체들로 분해할 수 있는 인간의 기본적인 인지능력에 기반을 두고 있기 때문이다."

멋진 비유

  • "현실의 객체보다 더 많은 일을 할 수 있는 소프트웨어 객체의 특징을 의인화라고 부른다."
  • "사람은 기계의 외부에 부착된 사각형과 원 모양의 버튼을 이용해서만 기계와 상호작용 할 수 있다. 사각형 모양의 버튼을 누르면 객체의 상태를 변경할 수 있다... 원 모양의 버튼을 누르면 객체의 상태를 조회할 수 있다... 사용자는 객체가 제공하는 명령버튼과 쿼리버튼으로 구성된 인터페이스를 통해서만 객체에 접근할 수 있다... 개인적으로 생각하는 기계 은유의 가장 큰 장점은 객체 캡슐화를 직관적이고 시각적으로 묘사한다는 점이다."

깊은 원리 이해

  • "메모리 내부의 비트열을 직접 들여다 보면서 메모리 안에 들어 있는 값이 어떤 의미인지 말할 수 있는 사람은 아무도 없다. 어떤 메모리 조각에 들어있는 값의 의미는 그 값을 가져다 자신의 용도에 맞게 사용하는 외부의 해석가에 의해 결정된다. 흔히 우리가 애플리케이션이라고 부르는 프로그램이 바로 그런 해석가의 일종이다."
  • "타입없는 무질서가 초래한 혼돈의 세상에 질려버린 사람들은 급기야 메모리 안의 데이터에 특정한 의미를 부여하기 시작했다. 사람들은 자신이 다뤄야하는 데이터의 용도와 행동에 따라 그것들을 분류했다. 어떤 데이터에 다른 데이터를 더하거나 빼거나 나누거나 곱할 수 있다면 그 데이터를 숫자형으로 분류했다. 데이터가 여러 문자로 구성돼있고 다른 문자와 연결될 수 있다면 그 데이터를 문자열형으로 분류했다. 데이터를 이용해 어떤 사실에 대한 참/거짓을 이야기할 수 있다면 그 데이터는 논려형으로 분류했다."
  • "컴퓨터 안에 살아가는 데이터를 목적에 따라 분류하기 시작하면서 프로그래밍 언어 안에는 서서히 타입시스템이 자라나기 시작했다. 타입 시스템의 목적은 메모리 안의 모든 데이터가 비트열로 보임으로써 야기되는 혼란을 방지하는 것이다. 타입 시스템은 메모리 안에 저장된 0과 1에 대해 수행 가능한 작업과 불가능한 작업을 구분함으로써 데이터가 잘못 사용되는 것을 방지한다. 결과적으로 타입 시스템의 목적은 데이터가 잘못 사용되지 않도록 제약사항을 부과하는 것이다."

캡슐화 자율성

  • "훌륭한 객체지향 설계는 외부에 행동만을 제공하고 데이터는 행동뒤로 감춰야 한다. 이 원칙을 흔히 캡슐화라고 한다. 공용 인터페이스 뒤로 데이터를 캡슐화하라는 오래된 격언은 객체를 행동에 따라 분류하기 위해 지켜야 하는 기본적인 원칙이다. 데이터가 캡슐의 벽을 뚫고 객체의 인터페이스를 오염시키는 순간 객체의 분류체계는 급격히 위험에 노출되고 결과적으로 유연하지 못한 설계를 낳는다."
  • "객체는 자율적인 존재라는 점을 명심하라. 객체지향의 세계에서 객체는 다른 객체의 상태에 직접적으로 접근할 수도 상태를 변경할 수도 없다. 자율적인 객체는 스스로 자신의 상태를 책임져야 한다. 외부의 객체가 직접적으로 객체의 상태를 주무를 수 없다면 간접적으로 객체의 상태를 변경하거나 조회할 수 있는 방법이 필요하다. 이 시점에 행동이 무대위로 등장한다. 행동은 다른 객체로 하여금 간접적으로 객체의 상태를 변경하는 것을 가능하게 한다. 객체지향의 기본사상은 상태와 상태를 조작하기 위한 행동을 하나의 단위로 묶는 것이라는 점을 기억하라. 객체는 스스로의 행동에 의해서만 상태가 변경되는 것을 보장함으로써 객체의 자율성을 유지한다."

책임주도 설계

  • "행동에 따라 객체를 분류하기 위해서는 객체가 내부적으로 관리해야하는 데이터가 아니라 객체가 외부에 제공해야하는 행동을 먼저 생각해야 한다. 이를 위해서는 객체가 외부에 제공해야 하는 책임을 먼저 결정하고 그 책임을 수행하는데 적합한 데이터를 나중에 결정한후 데이터를 책임을 수행하는데 필요한 외부 인터페이스 뒤로 캡슐화해야 한다."

분리하기

  • "객체를 이용해 시스템을 분할하는 방법"
  • "타입은 객체를 분류하기 위해 사용하는 개념이다. 반면 클래스는 단지 타입을 구현할 수 있는 여러 구현 매커니즘 중 하나일 뿐이다. 실제로 자바스크립트 같은 프로토타입 기반의 언어에는 클래스가 존재하지 않는다. 그럼에도 객체지향 패러다임을 주도하는 대부분의 프로그래밍 언어는 클래스를 기반으로 하기 때문에 대부분의 사람들은 클래스와 타입을 동일한 개념이라고 생각한다... 클래스는 타입의 구현 외에도 코드를 재사용하는 용도로도 사용되기 때문에 클래스와 타입을 동일시 하는것은 수많은 오해와 혼란을 불러일으키곤 한다."
  • "객체지향 설계라는 예술은 객체에게 적절한 책임을 할당하는 것에서 시작된다. 책임은 객체지향 설계의 품질을 결정하는 가장 중요한 요소다. 책임이 불분명한 객체는 애플리케이션의 미래 역시 불분명하게 만든다. 얼마나 적절한 책임을 선택하느냐가 애플리케이션의 아름다움을 결정한다."
  • "세상을 더 작은 객체로 분해하는 것은 본질적으로 세상이 포함하고 있는 복잡성을 극복하기 위한 인간의 작은 몸부림이다. 인간은 좀 더 단순한 객체들로 주변을 분해함으로써 자신이 몸담고 있는 세상을 이해하려고 노력한다. 즉 객체란 인간이 분명하게 인지하고 구별할 수 있는 물리적인 또는 개념적인 경계를 지닌 어떤 것이다."
  • "애플리케이션의 기능은 더 작은 책임으로 분할되고 책임은 적절한 역할을 수행할 수 있는 객체에 의해 수행된다. 객체는 자신의 책임을 수행하는 도중에 다른 객체에게 도움을 요청하기도 한다. 결론적으로 시스템은 역할과 책임을 수행하는 객체로 분할되고 시스템의 기능은 객체간의 연쇄적인 요청과 응답의 흐름으로 구성된 협력으로 구성된다."
  • "데이터 추상화를 제공하는 클래스라는 빌딩블록..."
  • "책임은 객체지향 설계의 가장 중요한 재료다... 객체의 책임은 객체가 무엇을 알고 있는가와 무엇을 할 수 있는가로 구성된다. 크레이그 라만은 이러한 분류체계에 따라 객체의 책임을 크게 하는것과 아는것의 두가지 범주로 자세히 분류하고 있다."
  • "객체지향 설계는 협력에 참여하기 위해 어떤 객체가 어떤 책임을 수행해야 하고 어떤 객체로부터 메시지를 수신할 것인지를 결정하는 것으로부터 시작된다. 어떤 클래스가 필요하고 어떤 메서드를 포함해야 하는지를 결정하는 것은 책임과 메시지에 대한 대략적인 윤곽을 잡은 후에 시작해도 늦지 않다."

협력 = 요청 + 응답

  • "객체지향에 갓 입문한 사람들의 가장 흔한 실수는 협력이라는 문맥을 고려하지 않은 채 객체가 가져야할 상태와 행동부터 고민하기 시작한다는 것이다. 중요한 것은 개별 객체가 아니라 객체들 사이에 이뤄지는 협력이다. 객체지향 설계의 전체적인 품질을 결정하는 것은 개별 객체의 품질이 아니라 여러 객체들이 모여 이뤄내는 협력의 품질이다. 훌륭한 객체지향 설계자는 객체들 간의 요청과 응답속에서 창발하는 협력에 초점을 맞춰 애플리케이션을 설계한다. 협력이 자리를 잡으면 저절로 객체의 행동이 드러나고 뒤이어 적절한 객체의 상태가 결정된다."
  • "협력의 본질은 요청과 응답으로 연결되는 사람들의 네트워크다. 일반적으로 우리가 직면하게 되는 문제는 혼자만의 힘으로는 해결하기 어렵기 때문에 해결과정에 여러사람이 참여하게 된다. 이 과정 속에서 요청과 응답의 연쇄적인 흐름이 발생한다."
  • "객체와 객체 사이의 의미있는 연결을 링크라고 한다... 링크는 객체가 다른 객체를 참조할 수 있다는 것을 의미하며 이것은 일반적으로 한 객체가 다른 객체의 식별자를 알고 있는 것으로 표현된다."
  • "현실 세계의 객체와 객체지향 세계의 객체 사이에는 중요한 차이점이 있다. 현실속에서 앨리스는 스스로 음료를 마시는 능동적인 존재지만 음료는 스스로는 아무것도 할 수 없는 수동적인 존재다. 현실 세계라면 음료의 양을 줄여 상태를 변경시키는 주체는 음료를 목 안으로 밀어넣은 앨리스가 될 것이다. 그러나 객체지향의 세계에서 모든 객체는 자신의 상태를 스스로 관리하는 자율적인 존재다. 앨리스 객체의 키를 작게 만드는 것이 앨리스 자신인 것처럼 음료 객체의 양을 줄이는 것은 음료 자신이어야 한다. 따라서 앨리스는 직접적으로 음료의 상태를 변경할 수 없다. 단지 음료에게 자신이 음료를 마셨다는 메시지를 전달할 수 있을 뿐이다. 적절한 정도로 음료의 양을 줄이는 것은 메시지를 전달받은 음료 스스로의 몫이다... 앨리스는 자신이 먹은 양만큼 음료의 양을 줄여다라고 메시지를 전송한다. 이것이 앨리스가 음료를 마신다는 행동에 대한 모든 것이다. 음료의 양이 줄어들 것인지는 메시지를 수신한 음료가 결정할 사항이며 앨리스와는 무관하다."
  • "객체지향 애플리케이션의 아름다움을 결정하는 것이 협력이라면 협력이 얼마나 조화를 이루는지를 결정하는 것은 객체다. 결국 협력의 품질을 결정하는 것은 객체의 품질이다."
  • "객체는 충분히 협력적이어야 한다. 객체는 다른 객체의 요청에 충실히 귀 기울이고 다른 객체에게 적극적으로 도움을 요청할 정도로 열린 마음을 지녀야 한다."
  • "풍부한 매커니즘을 이용해 요청하고 응답할 수 있는 인간들의 세계와 달리 객체지향의 세계에서는 오직 한가지 의사소통 수단만이 존재한다. 이를 메시지라고 한다. 한 객체가 다른 객체에게 요청하는 것을 메시지를 전송한다고 말하고 다른 객체로부터 요청을 받는 것을 메시지를 수신한다고 말한다... 이때 메시지를 전송하는 객체를 송신자라고 부르고, 메시지를 수신하는 객체를 수신자라고 부른다."
  • "메시지와 메서드의 분리는 객체의 협력에 참여하는 객체들간의 자율성을 증진시킨다. 커피를 주문하는 협력 과정에서 커피 제조를 요청받은 바리스타는 커피 머신을 이용해 커피를 제조할 수도 잇지만 커피머신을 사용하지 않고 수작업만으로 커피를 제조할 수도 있다."
  • "외부의 요청이 무엇인지를 표현하는 메시지와 요청을 처리하기 위한 구체적인 방법인 메서드를 분리하는 것은 객체의 자율성을 높이는 핵심 매커니즘이다."

상태

  • "과거에 발생한 행동의 이력을 통해 현재 발생한 행동의 결과를 판단하는 방식은 복잡하고 번거로우며 이해하기 어렵다. 따라서 인간은 행동의 과정과 결과를 단순하게 기술하기 위해 상태라는 개념을 고안했다... 상태를 이용하면 과거의 모든 행동 이력을 설명하지 않고도 행동의 결과를 쉽게 예측하고 설명할 수 있다... 상태는 근본적으로 세상의 복잡성을 완화하고 인지 과부하를 줄일 수 있는 중요한 개념이다."
  • "흔히 객체를 상태와 행동을 함께 지닌 실체라고 정의한다. 이 말은 객체가 협력에 참여하기 위해 어떤 행동을 해야 한다면 그 행동을 하는데 필요한 상태도 함께 지니고 있어야 한다는 것을 의미한다."
  • "객체지향의 세계를 창조하는 개발자들의 주된 업무는 객체의 상태를 조회하고 객체의 상태를 변경하는 것이다. 일반적으로 객체의 상태를 조회하는 작업을 쿼리라고 하고 객체의 상태를 변경하는 작업을 명령이라고 한다."

대충 느낌만. 써봐야.

  • "애플리케이션을 협력하는 객체들의 공동체가 아닌 클래스로 구성된 설계도로 보는 관점은 유연하고 확장가능한 애플리케이션의 구축을 방해한다... 코드를 담는 클래스의 관점에서 메시지를 주고받는 객체의 관점으로 사고의 중심을 전환하는 것이다. 중요한 것은 어떤 클래스가 필요한가가 아니라 어떤 객체들이 어떤 메시지를 주고받으며 협력하는가다. 클래스는 객체들의 협력관계를 코드로 옮기는 도구에 불과하다."

패턴

  • "반복적으로 발생하는 문제와 해법의 쌍을 일컷는 디자인패턴"

0개의 댓글