객체지향의 사실과 오해 - 03장. 타입과 추상화

객체지향의 사실과 오해 3장

객체지향의 사실과 오해 - 03장. 타입과 추상화

03장. 타입과 추상화

일단 컴퓨터를 조작하는 것이 추상화를 구축하고, 조작하고, 추론하는 것에 관한 모든 것이라는 것을 깨닫고 나면 훌륭한 컴퓨터 프로그램을 작성하기 위한 중요한 전제 조건은 추상화를 정확하게 다루는 능력이라는 것이 명확해진다.

  • 키스 데블린(Keith Devlin)

이 장에서는 타입과 추상화에 대해 알아본다.

추상화를 먼제 보게 되는데
앞부분에서는 지하철 노선도를 예시로 추상화를 설명한다.

이런 지하철 노선도는 사실적인 지형과 축척은 무시하고 역 사이의 연결성에만 집중했다.

이런 노선도의 핵심은 지도가 당연히 가지는 정확성을 버리고 목적에 집중한 결과다.

승객이 알아야하는 사실만 정확하게 표현하고 몰라도 되는 정보는 무시함으로써 쉽고 단순하며 목적에 부합하는 노선도를 창조해 냈다.

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

추상화를 통한 복잡성 극복

사람들은 복잡한 현실을 이해하기 쉽고 예측 가능한 수준으로 현실을 분해하고 단순화 하는 전략을 따른다.

결국 추상화란 현실에서 출발하나 불필요한 부분을 제거하며 사물의 본질을 나타나게 하는 과정이다.
위에서 말헀던 지하철 노선도 또한 이에 해당한다.

그러나 만약 위 지하철 노선도를 지역의 자세한 위치 거리를 알고 싶을때 사용한다면??
전혀 도움이 되지 않는다.

결국 의도된 목적으로만 사용되어야 한다는 것이다.
결국 추상화는 목적에 의존적이게 된다.

말하고 싶은건 객체지향 패러다임은 객체라는 추상화를 통해 복잡성을 극복한다는 것이다.

객체지향과 추상화

모두 트럼프일 뿐

책에서는 앨리스와 트럼프 병사, 하트 왕, 하트 여왕 과 만나는 장면을 말하는데
여기서 주의 깊게 볼 것은

"기껏해야 트럼프에 불과해, 무서워할 필요 없어"

이 말이다.

사실 모든 병사, 신하, 왕, 여왕 모두 객체이다
서로 다른 모습을 하고 있고 다른 행동을 한다.

하지만 위에서 말한 말과 같이 결국 모두 트럼프이다.

앨리스는 모든 객체를 트럼프라는 하나의 개념으로 단순화해 보고 있는 것이다.
차이점은 무시한채 공통점만을 취해 단순화 한것이다.

차이점은 무시한채 유사성을 기반으로 추상화

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

위에서 말하던 내용의 연속이다.

위에서 말하던 병사, 신하, 왕, 여왕은 각각 서로 구별할 수 있다.
명확한 경계를 가지고 서로 구별할 수 있는 구체적인 사물
다시 말해 모두 객체이다.

근데 결국 모두 트럼프..

이런 인물들이 모두 트럼프라고 했을 때 생각나는 일반적인 외형, 행동 방식을 가지고 있기 때문에 모두 트럼프라고 말할 수 있는 것이다.

그리고 옆에 있는 토끼는 트럼프가 아니다.
당연히..

그래서 앨리스는 인물들을 두 개의 그룹으로 나눈다.

트럼프, 토끼로 인물들을 보며 복잡성을 감소시킨다.

개념

사람들은 공통적인 특성으로 객체를 여러 그룹으로 묶어 동시에 다뤄야 하는 가짓수를 줄여 상황을 단순화하려고 한다.

이런 공통점을 기반으로 객체를 묶기 위한 것을 개념이라고 한다.

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

위에서 말하던 병사, 신하, 왕, 여왕, 토끼는 모두 객체이다
여기서 몸이 납작하고 네모난 몸을 가진 객체만을 트럼프라는 개념으로 추상화한다.

여기서 트럼프는 이런 공통점을 가진 객체들을 포함할 수 있는 개념이다.

그래서 이 개념을 사용하면 객체를 여러 그룹으로 묶어 분류할 수 있다.

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

개념은 객체를 분류할 수 있는 틀을 제공한다.
결국 주변의 복잡한 객체들은 단지 몇 가지 개념의 인스턴스일 뿐이다.

개념의 세 가지 관점

일반적으로 객체의 분류 장치로서 개념을 말할때 세가지 관점을 같이 언급한다.

  • 심볼: 개념을 가르키는 간략한 이름, 명칭
  • 내연: 개념의 완전한 정의, 내연의 의미를 이용해 개념에 속하는 지 확인할 수 있다.
  • 외연: 개념에 속하는 모든 개념의 집합

위에서 계속 예시로 들던 트럼프를 사용해서 설명할 수 있다.

우선 심볼은 개념을 가르키는 이름이다.
예시로 트럼프라는 이름은 개념의 심볼이 된다.

내연이란 개념의 의미를 나타낸다.
몸이 납작하고 네모난 몸을 가진 트럼프에 대한 설명이 바로 내연이다.
즉, 개념을 객체에 적용할 수 있는지 여부를 판단하기 위한 조건이다.

외연은 개념에 속하는 객체들, 즉 개념의 인스턴스들이 모인 집합을 말한다.
위에서 병사, 신하, 왕, 여왕 모두 트럼프의 외연을 구성하는 객체 집합에 속한다.

  • 심볼: 트럼프
  • 내연: 몸이 납작하고 네모난 몸을 가진 객체
  • 외연: 병사, 신하, 왕, 여왕, 등등

이런 개념을 이용해 공통점을 가진 객체를 분류하는 것은 복잡성을 극복하는 데 사용하는 가장 기본적인 수단이다.

클래스가 가장 유명한 것을 보면 대충 느낌이 온다.

객체를 분류하기 위한 틀

분류란 객체에 특정한 개념을 적용하는 작업이다.
객체에 특정한 개념을 적용하기로 결심했을 때 우리는 그 객체를 특정한 집합의 멤버로 분류하고 있는 것이다.

분류는 객체지향에서 가장 중요한 개념 중 하나다.
객체를 적절한 개념에 따라 분류하지 못한 경우 유지보수가 어렵고 변화에 쉽게 대처하지 못한다..

최대한 객체를 적절한 장소에 두고 최대한 직관적으로 분류하자.

분류는 추상화를 위한 도구다

말하던 두가지를 다시 생각해보자

  • 추상화는 구체적인 사물 간의 공통점을 취하고 차이점을 버리는 일반화를 통해 단순화하는 것이다.
  • 추상화는 중요한 부분을 강조하기 위해 불필요한 사항을 제거해 단순화하는 것이다.

개념을 통해 객체를 분류하는 과정은 위 두가지 모두 사용한다.

개념은 객체들의 복잡성을 극복하기 위한 추상화 도구다.
우리고 매순간 복잡한 세상을 이해 가능한 수준으로 단순화하고 있다.

타입

타입은 개념이다

타입의 정의는 개념의 정의와 동일하다.

타입은 공통점을 기반으로 객체들을 묶기 위한 틀이다.

타입은 개념과 동일하다.
따라서 타입이란 우리가 인식하고 있는 다양한 사물이나 객체에 적용할 수 있는 아이디어나 관념을 의미한다.
어떤 객체에 타입을 적용할 수 있을 때 그 객체를 타입의 인스턴스라고 한다.

근데 동일하다고 해도..
기계적인 의미로는 살짝 다르다.

데이터 타입

  1. 타입은 데이터가 어떻게 사용되느냐에 관한 것이다.
  2. 타입에 속한 데이터를 메모리에 어떻게 표현하는지는 외부로부터 감춰진다.

데이터 타입은 메모리 안에 저장된 데이터의 종류를 분류하는데 사용하는 메모리 집합에 관한 메타데이터다.
데이터에 대한 분류는 암시적으로 어떤 종류의 연산이 해당 데이터에 대해 수행될 수 있는지를 결정한다.

객체와 타입

위에서 말한 타입과 객체지향의 타입에는 깊은 연관성이 있다.

프로그래밍에서 객체는 일종의 데이터처럼 사용한다.
따라서 객체를 타입에 따라 분류하고 그 타입에 이름을 붙이는 것
이는 새로운 데이터 타입을 선언하는 것과 같다.

그러면 객체는 데이터인가?
XX

객체에서 중요한 것은 행동이다.
상태는 행동의 결과로 초래된 부수효과를 표현하기 위한 추상적인 개념이다.

결국 객체를 만들 때는 객체의 행동을 가장 중요하게 고려해야한다.
즉, 어떤 책임을 지녀야하는지 정하는 것이 핵심이다..

데이터 타입에서 말한 두가지는
객체의 타입에 맞게 다시 말할 수 있는데

  1. 객체가 어떤 타입에 속하는지를 결정하는 것은 행동이다.
    • 같은 행동을 한다면 같은 타입으로 분류할 수 있다.
  2. 객체의 내부적 표현은 외부로부터 감춰진다.
    • 행동을 수행할 수만 있다면 내부 상태를 어떻게 하더라도 무방하다.

행동이 우선이다

두가지 중 첫번째에 따르면 어떤 행동을 하느냐에 따라 타입이 결정된다.
두번째에 따르면 타입은 내부 표현과는 상관이 없다.

객체 내부 표현이 다르더라도 동일한 행동을 한다면 그 객체들은 같은 타입이라는 것이다.
따라서 동일한 책임을 수행한다면 동일한 타입에 속한다. 라고 볼 수 있다.

이는 객체를 타입으로 분류할 때 사용하는 기준을 보여준다.
행동.

타입이 행동에 의해 결정된다는 사실은 몇 가지 원리 원칙의 의미를 부여한다.

  • 같은 타입에 속한 객체는 행동이 동일하다면 서로 다른 데이터를 가질 수 있다.
    • 동일한 행동 == 동일한 책임 == 동일한 메세지 수신
      메시지를 처리하는 방식이 다를 수 있다.!

이는 다형성에 의미를 부여한다.

  • 데이터의 내부 표현 방식과 무관하게 행동만이 고려 대상이다.
    • 이는 외부에 데이터를 감춰야 한다는 것을 의미한다.

이는 캡슐화에 의미를 부여한다.

타입의 계층

트럼프 계층

병사, 신하, 왕, 왕비 들은 정말로 트럼프인가??

사실 트럼프는 카드 게임을 할 때 사용하는 트럼프를 생각한다.
실제로 위 예시들이 그런 트럼프인가?? 하면 또 아니다..

트럼프의 몇가지 특징을 공유하는 '트럼프 인간'으로 보는 것이다.

이를 객체지향의 관점에서 보면
같은 타입은 같은 행동을 해야한다.
그리고 트럼프 인간은 트럼프의 행동과 똑같지는 않다.

  • 트럼프: 납작 엎드릴 수 있고 뒤집어질 수 있다.
  • 트럼프 인간: 납작 엎드릴 수 있고 뒤집어질 수 있고 걸을 때마다 몸이 종이처럼 펄럭일 수 있다.

결국 트럼프 인간 타입은 트럼프 타입에 추가적인 행동을 더한것이다.

그래서 정리하면
트럼프 > 트럼프 인간
트럼프는 트럼프 인간을 포괄하는 더 일반적인 개념이다.

이런 관계를 일반화/특수화 관계라 한다.

일반화/특수화 관계

행동이 객체의 타입을 구별하는 것이기 때문에

한 타입이 다른 타입보다 더 특수하게 다른 한 타입은 더 일반적으로 행동해야한다.

더 일반적/ 더 특수한??

특수한 타입이라는 것은 일반적인 타입이 가진 행동을 하면서~
추가로 행동을 추가한 타입이라 볼 수 있다.

근데 여기서
타입의 내연을 의미하는 행동의 가짓수와 외연을 의미하는 집합의 크기는 서로 반대이다.

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

  • 왜냐면 특수 타입이 일반 타입의 부분집합이니까..

반대로 특수한 타입은 일반적인 타입보다 더 많은 수의 행동을 가지지만 더 적은 크기의 외연 집합을 가진다.

슈퍼타입과 서브타입

일반적/특수한 타입을 각각 슈퍼타입, 서브타입이라 한다.

  • 트럼프
    • 엎드릴 수 있다.
    • 뒤집어질 수 있다.
  • 트럼프 인간
    • 걸을 수 있다.

일반화는 추상화를 위한 도구다

추상화는 중요한 부분 강조를 위해 불필요한 사항을 제거시켜 단순하게 만드는 것이다.
일반화/특수화는 이를 활용하는 예다.

앨리스가 트럼프. 라고 말한 것은
걸을 수 있는 트럼프 인간의 행동을 제거하고 트럼프의 특성에만 집중한 것이다.
왜냐면?? 그 행동은 불필요 했으니까.

순서대로 보면

  • 트럼프 인간: 차이점 배제 공통점으로 분류
  • 트럼프: 불필요한 특성 배제 더 포괄적으로 일반화

정적 모델

타입의 목적

그래서 왜 타입을 사용해야하는데??
그냥 객체만 다루면 안되나??

인간의 인지능력으로는 동적으로 변하는 객체의 복잡성을 극복하기 너무 어렵다..

타입은 동적으로 변하는 상태를 정적인 모습으로 다룰 수 있게 해준다.

  • 상태에 복잡성을 부과하는 요소를 제거함으로써 정적인 모습으로..

그래서 결국 타입은 추상화다

이런 관점에서 타입은 추상화다.

타입을 이용하면 객체의 동적인 특성을 추상화할 수 있다.

타입은 객체의 상태 변경이라는 복잡성을 단순화할 수 있는 효과적인 방법이다.

동적 모델과 정적 모델

우선 한가지를 알고 가자

스냅샷이란 특정 시점에 구체적으로 어떤 상태를 가지는지를 말한다.

이 스냅샷은 객체 다이어그램이라고도 불린다.

실제로 객체가 살아 움직이는 동안 상태가 어떻게 변하고 행동하는지를 표착하는 것을 동적모델이라고 한다.

그리고 객체가 가질 수 있는 상태와 모든 행동을 시간에 독립적으로 표현하는 것을 타입모델이라고 한다.
그리고 이는 정적모델이라고도 한다.

프로그래밍에서
클래스를 작성하는 시점에는 시스템을 정적인 관점에서
실행중 객체의 상태 변경을 보고 디버깅 하는 것은 동적인 관점에서 보는 것이다.

클래스

보통 정적인 모델은 클래스를 이용해 구현한다.

따라서 타입을 구현하는 가장 보편적인 방법은 클래스를 이용하는 것이다.

근데 왜 이 클래스가 유명할까??
뭐 프로토타입 이런것도 존재하는데

사람들은 클래스와 타입을 동일한 개념으로 생각한다.
근데 이 클래스와 타입을 구분하는 것은 설계를 유연하게 유지하기 위한 바탕이 된다.

  • 클래스는 타입 구현 외에도 코드를 재사용하는 용도로도 많이 사용되기 때문.

정리하자면

  • 객체를 분류하는 기준은 타입
  • 타입을 나누는 기준은 행동
    이 두가지만 기억하자

그리고 클래스는
객체를 분류하기 위해 타입을 결정하고 타입을 구현할 수 있는 한가지 방법일 뿐이다.

결국 중요한것은 동적으로 변하는 상태, 상태를 변경하는 행동이다.

다음 장은 객체지향의 사실과 오해 4장 여기서.