Back-end/Study <객체지향의 사실과 오해>

[GDSC] 북 스터디 : 03_타입과 추상화

Uykm 2023. 11. 12. 05:06

▼ What ?

이번 챕터에서도 "이상한 나라 앨리스" 에 나오는 장면을 가지고 '타입''추상화' 라는 개념에 대해 다룬다. '타입' 과 '추상화' 가 왜 필요하며 두 개념 사이에 어떤 관계가 있는지, 그리고 객체지향을 설계하는 과정에서 객체를 생각할 때 필요한 관점 두 가지가 무엇인지에 대한 이야기를 담고 있다.


▼ Summory & Comment

 

이 챕터를 읽고 나서 기억에 남는 말 !

 

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

  • 저자가 한 말은 아니고, 리처드 파인만이 한 말을 책에 가져온 것이지만, 추상화가 왜 필요하고 추상화를 어떻게 해야 하는지를 한 줄로 담아내고 있는 말인 것 같아서 기억에 남았다.

 


 

추상화를 통한 복잡성 극복

 

  • 추상화에 대한 이야기는 헤리 벡이 창조한 영국 '지하철 노선도' 로부터 시작된다.

  • 헤리 백이 창조한 '지하철 노선도' 가 현대에도 그대로 적용된 이유는, 필요한 부분이 무엇이고 버려야 할 것이 무엇인지를 명확하게 파악했기 때문이다.
    ➜ 지형 표현, 정확한 위치, 역들 간의 실제 거리를 제거하여 실제의 지하철 노선도의 복잡성을 제거했다.
    ➜ 이는 곧 헤리 백이 사람들이 노선도를 확인하는 목적이 무엇인지 파악하고 역들 사이의 연결성, 즉 필요한 부분만 남긴 것을 알 수 있다.

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

  • 두 가지 추상화 기법

    1. 구체적인 사물들 간의 공통점은 취하고 차이점을 버리는 일반화를 통해 단순하게 만드는 것.

    2. 중요한 부분(역들 사이의 연결 관계)을 강조하기 위해 불필요한 세부 사항(지형, 위치, 거리)을 제거함으로써 단순하게 만드는 것.

 


 

객체지향과 추상화

 

  • 앨리스가 이상한 나라의 정원사들과 병사들, 여왕과 왕을 보며 "기껏해야 트럼프에 불과해" 라고 하는 장면
    ➜ 정원에 있던 많은 객체들을 종이 조각 같다는 공통점을 가지고 '트럼프' 라는 개념으로 단순화, 즉 추상화하였다.
    ➜ 공통점을 가지고 객체들을 묶기 위한 그릇을 '개념' 이라 한다 !

  • 이 '개념' 이라는 단어는 내가 블로그에 정리를 할 때 모든 글마다 항상 쓰는데, 내가 무슨 글을 썼는지 일일히 나열하지 않아도 간략하게 표현해낼 수 있는 마법의 단어이기 때문이다.
    ➜ 즉, 이 복잡한 객체지향의 세계를 단순화할 수 있게 해주는 도구이다 !

  • 이러한 개념을 적용한 객체를 '인스턴스' 라고 한다.
    ( 앨리스는 이 '트럼프' 라는 개념을 정원사, 병사, 여왕, 왕 등에 적용한 것이다. )

  • 개념은 다음처럼 세 가지 구성 요소를 갖고 있다.

    • 심볼(Symbol) (이름) 트럼프.

    • 내연(Intension)(설명)  몸이 납작하고 두 순과 두 발은 네모 귀퉁이에 달려 있는 등장인물.

    • 외연(Extension)(객체의 집합)  정원사, 병사, 신하, 왕자와 공주, 하객으로 참석한 왕과 왕비들, 하트 잭, 하트 킹과 하트 퀸.

  • 이러한 특정한 '개념' 을 객체에 적용시켜 해당 객체를 특정한 그룹에 포함시키는 작업을 '분류' 라고 한다 !
    '분류' 는 추상화를 위한 '도구' 이다.
    ➜ 객체지향 패러다임이 복잡성을 극복하는 데 가장 중요한 역할을 한 매우 중요한 개념 !

 


 

타입

 

  • '타입(Type)' 은 앞서 말한 '개념' 과 같은 의미를 담고 있다. (은유)
    ➜ 하지만, 컴퓨터 세계에서의 '타입' 은 '개념' 처럼 단순한 의미 X

  • "타입이 없다" = 메모리 안의 데이터를 다룰 수 있는 타입이 '비트열' 단 하나 뿐이다.
    타입이 없으면, 메모리 내부의 값을 체계적으로 다루는 것이 불가능하다.
    ➜ 그래서 이 메모리 안에 있는 데이터를 숫자형, 문자열, 논리형 이런 식으로 '분류' 하기 시작한 것 !

  • 타입의 용도

    • 이 데이터가 어떻게 사용되는가 ?
      ➜ 해당 데이터에 어떤 종류의 연산이 적용될 수 있는지를 알려준다.

    • 타입에 속한 데이터는 메모리에 어떤 식으로 표현되는가를 외부로부터 감춰준다.
      ➜ 사람들이 지하철의 지형이라 그런걸 다 알지 않아도 해당 역이 어떤 역으로 연결되는지만 알면 아무 문제 없이 지하철을 이용할 수 있듯이 !

  • 일단, 객체에서 중요한 것은 상태가 아닌 '행동' 이라는 점을 되새기자 !
    ➜ 객체지향 설계의 핵심은 '객체가 협력을 위해 어떤 책임을 지녀야 하는지' 를 결정하는 것이다.

  • 앞서 정리한 '타입의 용도'객체의 관점에서 생각해보자.
    '여기서 타입은 클래스인가?' 라는 생각이 들었는데 마지막 장을 보니 클래스는 타입 자체가 아니라 타입을 구현하는 메커니즘 중 하나라고 한다 !

    객체의 용도

    • 해당 객체가 어떤 행동을 수행하는가 ?
      ➜ 어떤 상태를 갖든 같은 행동을 수행하면 같은 타입의 객체이다.

    • 객체의 내부의 상태가 어떤지는 외부로부터 감춰준다.

  • 같은 타입에 속한 객체는 수행하는 행동만 동일하다면 어떤 데이터(상태)를 갖든 상관 X
    동일한 행동은 곧 동일한 책임이며, 동일한 책임은 곧 동일한 메시지 수신을 의미한다.
      하지만, 메시지를 수신하는 방식은 다 다를 수 있다.
    ( 내부의 데이터, 즉 상태가 다르기 때문이다. )

    • 객체지향의 중요한 특성인  '다형성' 동일한 요청에 대해 서로 다른 방식으로 응답할 수 있는 능력을 말한다.
      ➜ 이는 즉 다형적인 객체동일한 타입에 속한다고 말해볼 수 있다.
      ( 다형성 : 어떤 객체의 속성이나 기능이 상황에 따라 여러 가지 형태를 가질 수 있는 성질. )

    • 또한, 객체의 내부 데이터에 무관하게 행동만을 외부에 제공행동만을 고려하는 점에서 또 하나의 개념인 '캡슐화' 를 떠올려야 한다.
      이전 챕터에서도 나왔던 "책임-주도 설계" 방식은 객체의 책임(행동)을 먼저 생각한 다음에 데이터(상태)를 결정하는 방식을 말하고,  그 반대가 "데이터-주도 설계" 이다.

    • 여기서 생긴 의문점,
      ' 저자는 상태가 아닌 행동으로 분류하는 것을 강조하는데, 앞서 엘리스가 "기껏해야 트럼프에 불과해" 라고 한 것을 보면 앨리스가 정원에 들어선 하트 킹, 하트 퀸, 다이아 병사, 스페이드 정원사 등을 '트럼프' 라는 타입(개념)으로 분류한 이유가 그들의 공통적인 외형, 즉 상태 때문이지 않았나? 행동을 보고 분류를 한 것이라면, 어떤 행동을 보고 분류한거지?'
      저자는 앨리스가 그러한 외형을 보고 트럼프라는 동일한 개념(타입)으로 묶어 생각한 것이었다고 말한 것이 아니었다.
      그러한 외형들로 인해 걸을 때마다 종이 같은 몸이 좌우로 펄럭거리는 행동을 보고 분류한 것!
      무의식적으로 정원에 있는 군주들을 '트럼프' 의 행동방식이 아니라 외형, 즉 상태로 분류하려고 했던 내 잘못된 접근 방식이 이러한 의문점을 만들어낸 것 같다.

    • 이를 "책임-주도 설계" 방식으로 설계해본다고 하면,
      트럼프 타입에 해당하는 객체들의 외형을 미리 결정하고 행동을 구현하는 것이 아니라, 트럼프 타입의 객체들은 어떤 행동을 해야할지를 먼저 결정하고, 그 행동을 위한 외형, 즉 어떤 상태를 부여해야 할지는 그때 가서 선택하면 된다.
      즉, 객체지향 프로그래밍에서 중요한 것은 어떤 작업이 필요한지를 먼저 생각하고 그 작업을 할당할 객체들을 생성한 후에 필요한 데이터(상태)를 저장해주는 절차를 따르는 것이 올바르다.
      ( 사실, 어떤 데이터(상태)를 저장할지를 먼저 정하고 그에 따른 작업(행동)을 결정하는 방식은 그냥 생각만 해봐도 비효율적이고 체계적이지 못하다는 느낌이 든다. )

 


 

타입의 계층

 

  • 트럼프(일반) vs 트럼프 인간(특수)

    • 내연의 관점
      ➜ '트럼프 인간' 은 일반 트럼프 카드보다 좀 더 특화된 행동추가적으로 한다.

    • 외연의 관점
      ➜ 모든 '트럼프 인간' 은 '트럼프' 이다.
      ➜ '트럼프 인간' 의 외연은 '트럼프 카드' 의 외연의 부분집합에 해당한다.
      ( 이 부분에서 객체지향에서의 '상속' 이 떠올랐다. )

  • 일반화(Generalization) / 특수화(Specialization)

    • '트럼프' 는 '트럼프 인간' 보다 더 일반적인 개념, 즉 포괄적인 개념이다.
      타입 간의  '일반화/특수화' 관계를 결정하는 것은 객체의 내부에 있는 데이터(상태)가 아닌 외부에 제공하는 행동이라는 사실을 알 수 있다 !

    • 쉽게 정리하면, '일반적인 타입(트럼프)' 은 '특수한 타입(트럼프 인간)' 보다 더 적은 수의 행동을 가지는 동시에, '특수한 타입(트럼프 인간)' 은 '일반적인 타입(트럼프)' 이 가진 모든 행동공통적으로 수행할 수 있어야 한다.
      ➜ 행동의 가짓수 = 타입의 내연,
      '일반적인 타입' 은 더 적은 수의 행동을 가지지만 '특수한 타입' 보다 더 큰 외연 집합을 가진다.(포괄적)

    • 내연 ➜ 일반 < '특수'
      외연 ➜ '일반' > 특수

  • 일반적 타입(트럼프)은 '슈퍼 타입' ~ 납작 엎드릴 수 있다. 뒤짚어질 수 있다. (공통적인 행동)
    특수한 타입(트럼프 인간)은 '서브 타입' ~ 걸을 수 있다. (특수한 행동)
    서브 타입은 항상 슈퍼 타입을 대체 가능하다.
    서브 타입은 슈퍼 타입과 중복되는 행동을 생략 가능.
    슈퍼 타입의 행동은 서브 타입에게 '상속'된다.

  • 앨리스가 트럼프 인간을 보고 "기껏해야 트럼프에 불과해" 라고 한 장면
    ➜ 앞서 말한 두 가지 '추상화 기법' 이 동시에 사용되었다 !

    1. 정원에 있던 세 정원사들을 외형에서의 차이점은 배제하고 공통점만 생각해 '트럼프 인간' 으로 단순화하여 분류한 점.

    2. 종이처럼 펄럭이고 쉽게 뒤집어지는 트럼프의 특성에만 집중하고 걸어다니는 것과 같은 특수한 행동은 불필요하다 생각해 제거하여 다양한 트럼프 인간들을 '트럼프' 라는 것으로 단순화, 즉 일반화했다는 점.

 


 

정적 모델

 

  • 타입은 왜 필요할까 ?
    ➜ 너무나도 '동적인' 객체의 복잡성을 극복하기 위해서 !
    ➜  '앨리스' 의 키(상태)는 항상 변할 수 있는 가능성이 있지만, 모든 경우의 키를 생각하는 것이 아니라 '리스의 키는 변할 수 있다' 로 단순화하면, 시간에 따라 동적으로 변하는 앨리스의 상태(키)를 시간과 무관한 정적인 형태로 생각 가능!
    ➜ 우리가 앨리스라는 객체에 대해 생각해볼 때, 불필요한 시간과 상태 변화라는 동적인 요소를 배제하고 정적인 관점에서 생각할 수 있게 한다.
    ➜ 즉, '타입' 은 추상화 개념이라고 할 수 있다 !
    ➜ 시간에 따라 변할 수 있는 키와 같은 동적인 특성정적으로 추상화하여 복잡성을 단순화해준다.

  • 객체를 생각할 때 고려하는 두 가지 모델

    1. 동적 모델 : 객체의 '스냅샷(snapshot)' = 객체의 '다이어그램(diagram)'
      객체가 특정 시점에 어떤 상태를 가지는지 포착한 것.

    2. 정적 모델 : '타입 모델(type diagram)'
      앞서 말한 '앨리스의 키' 처럼, 객체가 가질 수 있는 상태 혹은 행동시간에 독립적으로 표현해낸 것.

  • 클래스를 작성하는 시점엔 시스템을 정적인 관점으로 접근하지만,
    애플리케이션을 실행해 객체의 상태 변경을 추적하고 디버깅하는 시점엔 객체를 동적인 모델로 바라본다.
    '정적'인 관점과 '동적'인 관점을 모두 이해해야 하는 이유 !

 

  • 객체지향 프로그래밍 언어에서 정적인 모델, 즉 타입을 구현하는 가장 보편적인 방법은 '클래스'를 이용하는 것이다.
    '타입' 과 '클래스' 는 동일한 개념이 아니다 !
    '타입' 은 객체를 분류하기 위한 개념, '클래스'는 타입을 구현하기 위한 메커니즘 중 하나이다.

  • '타입' 과 '클래스' 를 구분할 줄 아는 것은 유연한 설계의 베이스가 되어준다.
    ( 클래스의 역할이 타입을 구현하는 것만이 아니라 코드를 재사용하기 위함도 있기 때문에 ! )
    하지만, 이 챕터에서 꼭 이해하고 알아가야 할 사실은 객체를 분류하는 기준'타입' 이며, 그런 타입을 다시 나눠주는 기준은 객체의 '행동'이라는 사실과 타입을 구현하는 방법 중 하나가 '클래스' 라는 정도이다 !

 


▼ Study

 

객체의 스냅샷은 정적 모델?

 

  • 객체가 특정한 시점에 가지는 상태를 표현하는 것을 '객체의 스냅샷' 이라고 하며 객체가 어떻게 변하고 행동하는지를 포착하는 것을 '동적 모델' 이라고 하는데, 이 '객체의 스냅샷' 이라는 건 특정한 시점을 포착하는 것이니까 정적 모델 쪽에 가까운 것이 아닌가?
    여기서 말하는 '동적 모델' 은 변할 수 있는 모델을 의미하는 것이기 때문에, '객체의 스냅샷' 이 정적이라고는 할 수 있지만 이 '동적 모델' 이라는 것을 설명해주기 위해 나온 개념이기 때문에, 이 '객체의 스냅샷' 이 '정적 모델' 이냐, '동적 모델' 이냐를 따지는 것은 적절하지 않은 것 같다.

 


 

 

"앨리스의 키"를 고려하는 것이 객체의 행위에 집중하는 것이 맞나?

 

  • 책에서 타입은 행위에 집중한다고 했는데 위처럼 앨리스의 키를 생각하는 것은 오히려 상태에 집중하는 격이 아닌지 하는 이야기가 나왔다.
    앨리스의 키가 변화하는 것은 앨리스가 한 행동들로 인해 발생한 결과이기 때문에 결국 앨리스의 행동에 집중한 것이 맞는 것 같다고 결론을 지었다.

 


 

프로그램을 실행한 시점에 바로 적용되는 연산도 동적이라고 봐야하나?

 

  • 클래스를 작성하는 시점엔 시스템을 정적인 관점으로 접근하지만, 애플리케이션을 실행해 객체의 상태 변경을 추적하고 디버깅하는 시점엔 객체를 동적인 모델로 바라본다고 하면, 실행한 바로 그시점(0초)에 적용되는 연산도 동적이라고 봐야 한다.

 


 

Issue_1

이 파트에서 저자는 상태가 아닌 행동으로 분류하는 것을 강조했습니다. 앞서 앨리스가 "기껏해야 트럼프에 불과해" 라고 한 부분에서 '앨리스가 정원에 들어선 하트 킹, 하트 퀸, 다이아 병사, 스페이드 정원사 등을 '트럼프' 라는 타입(개념)으로 분류한 이유가 그들의 공통적인 외형, 즉 상태로 분류한 것인 줄 알았는데, 행동으로 분류한 것이라면 어떤 행동으로 분류를 한거지?' 라는 의문이 들었습니다.

 

  • 저자는 앨리스가 그러한 외형을 보고 트럼프라는 동일한 개념(타입)으로 묶어 생각한 것이었다고 말한 것이 아니었다. 그러한 외형들로 인해 걸을 때마다 종이 같은 몸이 좌우로 펄럭거리는 행동을 보고 분류한 것이라고 할 수 있다.

 


 

Issue_2

클래스는 타입을 구현할 수 있는 여러 구현 메커니즘 중 하나라고 했는데, 타입 == 개념이고 개념은 3가지로 분류 가능하다고 했습니다.(심볼, 내연, 외연) 이것을 클래스로 표현한다고 했을 때 3가지 분류에 어떻게 구현할 수 있을까요?
ex) 자동차, 사람

 

  • 클래스의 심볼은 클래스명(Car)이고, 클래스의 내연은 클래스 내에 구현되어 있는 변수(기름의 양), 메서드(가속, 정지) 등 모두를 포함하는 것 같습니다. 그리고 외연은 클래스로부터 생성된 인스턴스들(내 차,친구 차, 부모님 차)이라고 할 수 있을 것 같습니다.

 


 

Issue_3

일반화/특수화 관계에서 일반적인 타입은 특수한 타입보다 더 적은 수의 행동을 가지지만 더 큰 크기의 외연 집합을 가진다.

일반적인 타입은 특수한 타입보다 외연의 크기는 더 크고 행동의 수는 더 적다?
외연의 크기가 크단 말이 특수한 타입이 일반적인 타입의 부분 집합이 되므로, 집합의 크기가 더 크다는 말일까?

 

  • 외연의 측면에선 일반적인 타입이 스마트폰이라 했을 때 특수한 타입은 갤럭시S21, 아이폰15 등이 될 수 있기 때문에, 일반적인 타입이 좀 더 포괄적인 개념이니 더 큰 외연집합을 가진다고 한 것입니다. 내연의 측면에선 일반적인 타입인 스마트폰은 스마트폰의 기본적인 기능만 갖고 있는 것이고, 특수한 타입은 갤럭시만 갖고 있는 특수한 기능, 아이폰만이 갖고 있는 특수한 기능까지 갖고 있을 수 있기 때문에 일반적인 타입보다 할 수 있는 행동이 더 많다는 것 같습니다.

 


 

Issue_4

타입은 시간에 따라 동적으로 변하는 엘리스의 상태를 시간과 무관한 정적인 모습으로 다룰 수 있게 해준다.

객체지향에서 타입은 지금까지 행위에 집중한다고 배웠는데 이건 오히려 상태에 집중하는 것이 아닌지 의문이 들어요.

 

  • 깃허브 이슈를 보기 전에 앞서서 이미 이에 대한 이야기를 해보고 결론을 지었다.

 


 

Issue_5

" 행동의 관점에서 더 일반적인 타입이란 무엇이고, 더 특수한 타입이란 무엇인가? 일반적인 타입이란 특수한 타입이 가진 모든 행동들 중에서 일부 행동만을 가지는 타입을 가리킨다 "

여기서 말하는 "일부 행동"의 범위가 명확하지 않은 것 같은데 다들 어떻게 생각하시나요?

 

  • 예를 들어, 스마트 TV 와 그냥 일반 TV가 있을 때, 스마트 TV는 일반 TV에서의 기본 기능들은 모두 갖고 있다. 이때 기본적인 TV기능이 "일부 행동" 인 것이고, 스마트 TV가 가지고 있는  미러링 같은 기능을 "특수한 행동" 이라고 할 수 있을 것 같다.

 


 

Issue_6

어떤 데이터에 어떤 연산자를 적용할 수 있느냐가 그 데이터의 타입을 결정한다는 점

어떤 연산자를 적용하는 부분이 행동이라고 생각하면 되겠죠?

 

  • 네, 행동이라고 생각하면 될 것 같습니다.